"The delete in the translation"javascript

Source: Internet
Author: User
Tags eval getbase

In this article, the author starts with the error about delete in the JavaScript object-oriented Programming Guide, detailing the implementation of the delete operation, limitations, and performance in different browsers and Plug-ins (refer to Firebug).

The following translation of the main parts.

... The book says

"The function is like a normal variable--it can be copied to a different variable or even deleted."

The following code fragment is attached as a description:

>>> var sum = function (A, b) {return a+b;};
>>> var add = sum;
>>> delete sum;
True
>>> typeof sum;

Can you find the problem in the fragment? The problem is that the operation to delete the sum variable should not succeed; the declaration of delete should not return true and typeof sum should not return to undefined. Because a variable cannot be deleted in JavaScript, at least it cannot be declared in this way.

So what happened with this example. It's a print error or a joke. I don't think so. This fragment is an actual output from the Firebug console, and Stoyan (the author of the story above) should be the quick test that it does. This seems to indicate that Firebug has some different deletion rules. It was Firebug who misled Stoyan. So what the hell is going on in there?

To answer this question, we need to understand how the delete operator works in Javascript: which can be deleted, which cannot be deleted, and why. I'll try to explain the details here. By observing the "strange" manifestations of firebug, we realize that it is in fact not "strange" at all; we'll delve into those details that are hidden behind when we declare variables, functions, assign attributes, and delete them; we'll look at the browser's implementation of this and some well-known bugs; We also discuss the rigorous mode (strict mode) in ECMAScript version 5 and how it changes the behavior of the delete operator.

The Javascript and ecmpscript I use interchangeably below are generally referred to as ECMAScript (unless the JavaScript™ implementation of Mozilla is explicitly mentioned).

Unsurprisingly, there are very few explanations for delete on the Web (I press: This article was written in January 2010). The MDC (MDN) resource is probably the most detailed of these, but unfortunately it misses out some interesting details that include the firebug of the above. The MSDN documentation is of little use. I. Theory | Theory

So, why can we delete an object's properties:

var x = {a:1};
Delete x.a; True

But you cannot delete a variable:

var x = 1;
Delete x; False

You cannot delete a function:

function X () {};
Delete x; False

Note: Delete returns false only if a property cannot be deleted.

To understand this, we need to first grasp some concepts: variable instantiation (variable instantiation) and intrinsic properties (property attributes) (translator: About properties and attributes The difference is seen in the reference article, which is intended to be translated into internal attributes according to the content described below--these are rarely mentioned in JavaScript books. In the following paragraphs I will try to briefly review these elements, and it is not difficult to understand them. If you are not concerned about the reasons behind their performance, you can skip this chapter. 1.1, type of code | Type of code

There are three types of executable code in the ECMAScript: Global-code-code-function-

The meanings of these categories are roughly as they are named, but they are quickly reviewed:

When a source file is viewed as a program, it executes within global scope (scope), which is considered a global code. In a browser environment, the contents of a SCRIPT element are usually parsed into a program and thus executed as a global code.

Of course, any code that executes directly in a function is considered a function code, in the context of a browser, the contents of the event property (e.g). <a onclick= "..." is usually parsed and executed as a function code.

Finally, the code that puts the built-in function eval is parsed as an eval code. We will soon see why this type is special. 1.2, the context of the Code execution | Execution Context

When the ECMAScript code executes, it always occurs in a determined execution context. The execution scope is an abstract entity that helps to understand how scopes and variable instantiations work. The above three types of executable code have their own execution context. When the function code executes, we say that the control end goes into the execution context of the function code, and when the global code executes, we say that the control end is in the execution contexts of the global code, and so on.

As you can see, the execution context is logically one stack (stack). First there may be a piece of global code, which has its own execution context, where a function may be called, which also has its own execution context, which may call another function, and so on. Even when a function recursively calls itself, it still enters a different execution context in each step of the call. 1.3. Activating objects and Variable objects | Activation Object/variable Object

Each execution context has a variable object (Variable object) associated with it. Like it, a variable object is also an abstract entity, a mechanism for describing variable instantiation. Interestingly, variables and functions declared in a section of the source code are actually added to the variable object as properties of the variable object (Variable object).

When control enters the execution context of global code, a global object is used as a variable object. This is precisely why globally declared variables and functions become properties of a global object:

var global_object = this;
var foo = 1;
Global_object.foo; 1
function Bar () {};
typeof Global_object.bar; "Function"

Ok, so the global variable becomes the property of the global function, so the local variables--what are the variables declared in the function code? In fact it's simple: they're also attributes of variable objects. The only difference is that in the function code, the variable object is not a global object, but rather an activation object (Activation object). An Activation object is created each time the execution context of the function code is entered.

The variables and functions declared in the function code are not the properties of the activated object: each argument of the function (arguments, the name of the corresponding formal parameter), and a special arguments object (arguments as the property name) Also becomes the property of the activation object. It should be noted that the activation object as an internal mechanism cannot in fact be accessed by program code.

(function (foo) {
    var bar = 2;
    function Baz () {};
        /* In the abstract process, the
        special ' arguments ' object becomes the property of the activated object of the function:
        activation_object.arguments = arguments;
        ... The parameter ' foo ' is the same:
        Activation_object.foo//1
        ... The variable ' bar ' is the same:
        Activation_object.bar//2
        ... The function ' Baz ' is the same:
        typeof Activation_object.baz//"function"
      * *

Finally, the variable declared in the Eval code becomes the property of the context's variable object (contexts ' s Variable object). Eval code simply uses the variable object in the execution context in which it is invoked.

var global_object = this;
Eval (' var foo = 1 ');
Global_object.foo; 1;

(function () {
    eval (' var bar = 2 ');
        /* Activation_object.bar in the abstract process
        ;//2
    *
1.4, properties of the internal properties | Property Attributes

Close to the subject. Now that we have a clear idea of what is happening to the variables (they are attributes), the remaining concepts that need to be understood are the intrinsic properties (property attributes). Each property has 0 to multiple such as internal properties--*readonly,dontenum,dontdelete and internal**. You can think of them as tags--a property may or may not have a particular intrinsic attribute. In today's discussion, we are interested in dontdelete.

When declaring variables and functions, they become variable objects (Variable object)-Either the activation object (in the function code), or the properties of the global object (in global code), which are accompanied by the generation of internal property dontdelete. However, any explicitly/implicitly assigned property does not generate a dontdelete. And that's essentially why we can remove some of the attributes and not remove the other reason.

var global_object = this;

/* ' foo ' is a property of a global object that is
    generated by a variable declaration and therefore has an internal property dontdelete
    That's why it can't be deleted. * *
var foo = 1;
Delete foo; False
typeof Foo;//"Number"/

* ' Bar ' is a property of a global object that is
    generated by a variable declaration and therefore owns the Dontdelete
    This is why it cannot be deleted as well.
function Bar () {};
Delete bar; False
typeof bar;//"function"/

* ' Baz ' is also a property of the global object,
    However, it is generated by assigning values to the property, so there is no dontdelete
    This is why it can be removed * *
Global_object.baz = "Baz";
Delete Global_object.baz; True
1.5. Built-in and Dontdelete | Build-ins and Dontdelete

So that's why all of this happens: a special internal property of a property controls whether the property can be deleted. Note: Some properties of the built-in object have internal property dontdelete and cannot be deleted, and special arguments variables (as we know, the properties of the activated object) have dontdelete; the length (return parameter lengths) property of any function instance has Dontdelete:

(function () {
    //Cannot delete ' arguments ' because there is dontdelete
    delete arguments;//false;
    typeof arguments; "Object"

    //cannot delete the length of the function because there is dontdelete function
    f () {};
    Delete f.length; false;
    typeof F.length; "Number"

Properties associated with the function arguments also have dontdelete and cannot be deleted

(function (foo,bar) {
    delete foo;//False
    foo;//1

    Delete bar;//False
    bar;//"Bah"
1.6, not declared variable assignment | Undeclared Assignments

As you may recall, an undeclared variable assignment becomes a property of the global object, unless the property is found elsewhere in the scope chain. Now we understand the difference between attribute assignment and variable declaration-the latter generates Dontdelete and the former is not generated-which is why undeclared variable assignments can be deleted.

var global_object = this;

/* The properties of the global object are generated by variable declaration, owning Dontdelete
/var foo = 1;

/* To generate properties of global objects by assigning values to undeclared variables without dontdelete
/bar = 2;

Delete foo; False

Note: Internal properties are determined at property generation, and subsequent assignment procedures do not alter the intrinsic properties of an existing property. It is important to understand this distinction.

* * * "foo" created while generating Dontdelete
/function foo () {};

/* After the assignment process does not change the intrinsic properties of existing attributes, Dontdelete still exists * *
foo = 1;
Delete foo; false;
typeof Foo; "Number"/

* But when a nonexistent property is assigned, a property without an intrinsic property is created, so there is no dontdelete
/this.bar = 1;
Delete bar; True
second, the chaos of Firebug | Firebug Confusion

So, what happened in Firebug. Why the variables declared in the console can be deleted, rather than what we discussed earlier. As I said before, the Eval code has a special behavior when it handles variable declarations: variables declared in Eval code actually generate a property that has no dontdelete.

Eval (' var foo = 1; ');
Foo 1
delete foo;//True

The same is true in the function code:

(function () {
    eval (' var foo = 1; ');
    Foo 1
    delete foo;//True
    typeof foo;//"Undefined"

And this is the reason for the abnormal behavior in Firebug. All of the debug text in the console appears to be compiled and executed with Eval code, rather than in global or function code. Obviously, the variable declarations are eventually generated with no dontdelete attributes, so they can be deleted. So be careful with the difference between common global code and FIREBUG console code. 2.1. Delete Variables via eval | Delete variables via eval

This interesting eval behavior, combined with another aspect of ECMAScript, can technically allow us to remove attributes that could not otherwise be deleted. This aspect is about function declarations--they can overwrite variables of the same name in the same execution context:

function X () {};
var x;

So why does a function declaration have precedence over a variable of the same name (or, in other words, the same property of a variable object (Variable))? This is because the instantiation of the function declaration is after the variable declaration, so you can overwrite them.

(Translator: A function declaration can only overwrite a variable with the same name as a declaration without assigning a value, if the value is assigned at the time of the Declaration (e.g). var x = 1 The procedure for assigning values is overridden by a variable assignment after the function has been initialized, as follows:

var x = 1;
function X () {};

The function declaration replaces not only the value of the property, but also its internal properties. If we declare a function through Eval, this function will also replace the previous one with its own internal property. And because the variables that are declared in Eval do not have dontdelete, instantiating this function will "theoretically" remove the existing Dontdelete intrinsic properties of the original attribute, making it possible to delete the property (and, of course, point the value to the newly generated function).

var x = 1;
/* Cannot delete, ' x ' has dontdelete*/
delete x;//False
typeof X;//"number"
//original reference from JavaScript Tutorial: http:// www.software8.co/wzjs/Javascript/
Eval (' function X () {} '); /* attribute ' X ' now points to function and should not have Dontdelete/ typeof x;//' function ' delete x;///Should be ' true ';

Unfortunately, this deception technique was unsuccessful in every browser I tried. I might have missed something here, or the behavior was so subtle that browsers didn't notice it.

(Translator: The problem here may be: the overwrite between the function declaration and the variable declaration is only the change of the value point, while the internal property dontdelete is determined at the initial declaration and no longer changes, and the variables and functions declared in the eval can only be deleted if they are not declared in their external context. With regard to the order of execution, because Eval is a function, its invocation is always after the other variables and functions in its external context, so the related internal properties are also determined, overwriting only the point of the value. as follows:)

/* The  First alert returns "undefined" because the assignment procedure is after the procedure is declared and the eval executes, and
    the second alert returns "false" because, although the position of the X declaration is after Eval,
    However, the execution of Eval is after the variable declaration and therefore cannot be removed
/eval (' Alert (x); alert (delete x) ');
third, the browser compliance | Browsers Compliance

It is important to understand how things work, but the actual implementation is more important. Do browsers adhere to these criteria when creating and deleting variables/attributes? For the most part, yes.

I wrote a simple test unit to check the compliance of global, functional, and eval codes. The test unit also detects whether the return value of the delete operation and the property are deleted as expected. The return value of the delete is not as important as its actual result, and it is not important that the delete operation return TRUE or FALSE, and it is important that the owning/no dontdelete attribute is deleted.

Modern browsers generally adhere to the deletion rules, the following browsers all passed the test: Opera 7.54+, Firefox 1.0+, Safari 3.1.2+, Chrome 4+.

Safari 2.x and 3.0.4 have problems deleting function arguments, and it appears that these properties are created without dontdelete and therefore can be deleted. Safari 2.x has other problems--throw errors when no references are removed (for example, delete 1) (translator: IE also has); the function declaration generates the properties that can be deleted (oddly, the variable declaration is normal); the variable declaration in Eval becomes not removable (and the function declaration in eval is normal).

Similar to Safari, Konqueror (3.5, not 4.3) has the same problem with deleting arguments without references and deletions. 3.1, Gecko dontdelete bug

Gecko 1.8.x Browser--firefox 2.x, Camino 1.x, SeaMonkey 1.x, etc.--There is an interesting bug: an explicit assignment value gives an attribute the ability to remove its dontdelete, even if the property is generated by a variable or function declaration.

function foo () {};
Delete foo; false;
typeof Foo; "function"

this.foo = 1;
Delete foo; True

Surprisingly, Ie5.5-8 also passed most of the tests, in addition to deleting unreferenced throw errors (e.g). Delete 1, just like old Safari. However, while it is not immediately discovered that IE has a more serious bug, these bugs are about global objects. Four, IE bugs

In IE (at least in ie6-8), the following expression throws an exception (in global Code):

this.x = 1;

And the following is another:

var x =1;
Delete this.x; Typeerror:cannot Delete ' this.x '

This seems to indicate that in IE, variable declarations in global code do not generate a property with the same name as the global object. A property created by an assignment (This.x = 1) is then thrown with a delete x, and the property created by the variable declaration (var x = 1) is then thrown through the delete this.x (translator: The error message is the same as above in the ie6,7).

But not only that, in fact, properties created by an explicit assignment always throw an exception when deleted. This is not just a mistake, but a property that is created appears to have dontdelete intrinsic attributes that should not be available by rule:

this.x = 1;
Delete this.x; Typeerror:object doesn ' t support this action

On the other hand, undeclared variable assignments (those that generate the same properties as global objects) can be deleted correctly under IE:

x = 1;

But if you attempt to delete by using the This keyword (delete this.x), the above exception is thrown:

x = 1;

If summed up, we will find that in the global code ' delete This.x ' will never succeed. An exception is thrown when an attribute is generated by an explicit assignment (this.x = 1), and another exception is thrown when the property is generated by means of a declaration/Declaration variable (var x = 1 or x = 1). On the other hand, delete x throws an exception only if the assignment build property (this.x = 1) is displayed.

In September I discussed this issue, where Garrett Smith thought that the global variable object, the Global object, was implemented as a JScript object in IE, and that it was implemented by the host object.

We can confirm this theory in some way through several tests. Note that this and window seem to refer to the same object (if the ' = = = ' operator can be trusted), whereas the variable object Variable the object (the basis of the function declaration) is different from the this reference.

function GetBase () {return this;};

GetBase () = = = This.getbase (); False
this.getbase () = = This.getbase ()//True
window.getbase () = = This.getbase ()//True
v. Misunderstanding | Misconceptions

We cannot underestimate the importance of understanding the workings of things. I've seen some misconceptions about the delete operation on the web. For example, an answer (and a high level) on the StackOverflow explains that "delete is supposed to being no-op when target isn ' t". Now that we know the core of the delete operation, it is clear that the answer is incorrect. Delete does not differentiate between variables and attributes (in fact, these are references in the delete operation), but only the dontdelete (and whether the property already exists). vi, ' delete ' and host Object | ' Delete ' and host object

The algorithm for a delete is roughly like this:

1. Returns true 2 if the operand (operand) is not a reference
. If the object does not have a * * Direct property with the same name * *, return True (as we know, the object can be a global object or an activated object)
3. If the attribute already exists but has Dontdelete , return False

However, the behavior of the delete operation for host objects (host object) may be unpredictable. In fact this is not wrong: the host object (through a certain rule) allows any action to be implemented, such as reading (the internal [[get]] method), writing (The internal [[Write]] method), deleting (the internal [[[Delete]] method), and so on. This allows custom [[Delete]] behavior to cause confusion in the host object.

We've seen some problems with IE: throwing exceptions when you delete some objects (those that are implemented to host objects). Some versions of the Firef

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.