Constructor: constructor of an object. It is a function.
Prototype: the prototype of the constructor. Only functions have this attribute.
Isprototypeof: If object a exists in the original model chain of object OBJ, A. isprototypeof (OBJ) returns true, and OBJ must inherit the attributes of.
_ PROTO __: the prototype chain of the access object is the upper-level object of the current object, that is, the parent-level object of the object, which is not W3C or ecmascript standard, it is an implementation method that the browser inherits from the prototype. It exists in Firefox and chrome, and does not exist in IE. The original source chain of JS objects should be maintained by the JS engine and belong to "engine-level" data. The emergence of the __proto _ attribute allows the original chain to be modified, this makes it possible to discuss the prototype chain of JS objects within the scope of JS syntax.
In the object inheritance relationship, the constructor of the object OBJ actually exists in the prototype chain, that is, obj. constructor is actually obj. _ PROTO __. constructor, obj. hasownproperty ('constructor'); false
Function Y (){ This . Y = 99 ;} VaR OBJ =New Y (); console. Log (obj. constructor ); // Y Console. Log (obj. hasownproperty ( 'Constructor ')); // False Console. Log (obj. _ PROTO _. hasownproperty ( 'Constructor ')); // True // ===== Function X (){ This . X = 88 ;} Function Y (){ This . Y = 99 ;} Y. Prototype = New X (); VaR OBJ = New Y (); console. Log (obj. constructor ); // X Console. Log (obj. hasownproperty ( 'Constructor ')); // False Console. Log (obj. _ PROTO _. hasownproperty ( 'Constructor ')); // False Console. Log (obj. _ PROTO _. _ PROTO _. hasownproperty ( 'Constructor ')); // True
// ==================
// When accessing an object, obj. _ PROTO _. x = value must have obj. x = value, // The properties on OBJ. constructor. prototype will be saved in OBJ. _ PROTO. Function Y (){ This . Y = 99 ;} Y. Prototype = {A: 11 }; VaR OBJ = New Y (); obj. _ PROTO _. hasownproperty ( ""); // True Y. Prototype. = 77 ; Console. Log ([obj. A, obj. _ PROTO _. A, obj. Y, obj. _ PROTO _. Y]); // 77, 77, 99, Undefined and Y attributes are directly generated by the object constructor, rather than inherited from the prototype chain. */
// After the new operation constructs the OBJ object, when OBJ accesses the inherited attributes, It accesses the object through _ PROTO _ instead of obj. constructor. prototype access, obj. _ PROTO. _ does not point to OBJ. constructor. prototype, but points to the same object
//Therefore, if obj. constructor. prototype is modified to point to another object, the original properties of OBJ are not affected.
Y. Prototype = {B: 22 };
Console. Log (obj. B );//Undefined
Console. Log (obj. );//77
//Another example may be confusing.FunctionClassa (){VaRProp = 'hello'; arguments. callee. Prototype = {getprop:Function(){ReturnProp ;}}}VaRObj1 =NewClassa (); obj1.getprop ();//Error, object # <classa> has no method 'getprop'VaRObj2 =NewClassa (); obj2.getprop ();//HelloBecause when obj1 is initialized, classa. prototype is modified. Before modification, obj1 has been instantiated.
In: if the object OBJ has an attribute property (including inherited and non-enumerated attributes, unlike in a for in loop, for in ignores non-enumerated attributes ), then 'properties' in OBJ returns true, which does not exist in the early version of JavaScript.
Propertyisenumerable: If the property on the object OBJ can be listed (can be traversed cyclically by for in), then obj. propertyisenumerable ('properties') returns true. It is worth noting that propertyisenumerable is regarded as false for all inherited attributes, which is generally considered a design error in the ECMA script specification.
Hasownproperty: If the property on Object obj is not inherited, obj. hasownproperty ('properties') returns true.
Delete: delete attributes of an object. inherited attributes cannot be deleted.The variables declared using VAR cannot be deleted, but the function declaration can be executed in the firebug and ie9 debuggers.CodeAnd you will find that the global variables have been deleted. In fact, this will not happen in the Code on the page..
VaR F = Function () {}; F. Prototype = {X: 99 }; VaR O = New F; console. Log (O. hasownproperty ( 'X ')); // False Console. Log (O. X ); // 99 Delete O. X; console. Log (O. X ); // 99 VaR X = 1 ; Window. hasownproperty ( 'X '); // True Delete Window. X; console. Log (X ); // Error, X is not defined in Firefox bug, it will be 1 in chrome
Instanceof: If the OBJ object is an instance of the constructor fun, OBJ instanceof fun returns true,
It is worth noting that instanceof does not check the fun function, and its detection is based on the "prototype chain", if fun. prototype = obj. _ PROTO _ is true, or fun. prototype. isprototypeof (obj. if _ PROTO _) is true, OBJ instcaneof fun returns true, that isFun. prototype.Isprototypeof (OBJ) is true. (It is incorrect to write instanceof here based on fun. Prototype. constructor = obj. _ PROTO _. constructor is true)
Therefore, even if OBJ instanceof fun returns true, OBJ may not have the properties defined in the fun constructor, because fun is not necessarily the OBJ constructor.
The following code is used:
function F () {}; function G (){}; function K () {} f. prototype = New G (); var OBJ = New F (); console. log (OBJ instanceof F, OBJ instanceof G, F. prototype = obj. _ PROTO __, G. prototype. isprototypeof (obj. _ PROTO _); // true K. prototype = f. prototype; console. log (OBJ instanceof K ); // true var O ={}; O. _ PROTO _ = OBJ; console. log (O instanceof F ); // true function P () {} p. prototype. constructor = obj. _ PROTO __. constructor; console. log (OBJ instanceof P. prototype. constructor, OBJ instanceof P); // True False obj. _ PROTO _ = {}; console. log (OBJ instanceof F); // false G. prototype = {}; console. log (OBJ instanceof G); // false
//Another exampleFunctionA (){This. A = 'a ';}FunctionB (){This. B = 'B';} B. Prototype. constructor =;VaROBJ =NewB (); console. Log (OBJInstanceofB, OBJInstanceofA );//True, falseConsole. Log (B. Prototype = obj. _ PROTO __);//TrueConsole. Log (obj. constructor === A, obj. _ PROTO _. constructor === A, OBJInstanceofA );//True true false, indicating that instanceof is not based on the constructor
For more information about instanceof, test the following code:
FunctionP (){This. P = 11;};VaRPro =NewP ();FunctionX (){This. X = 88;}FunctionY (){This. Y = 99;} Y. Prototype=Pro;VaROBJ =NewY ();
1. Where is the object constructor?
Console. Log (obj. hasownproperty ('constructor '));//FalseConsole. Log (obj. constructor );//PConsole. Log (obj. _ PROTO _. constructor );//PConsole. Log (obj. _ PROTO _. Constructor=== Y. Prototype. constructor );//True
This indicates that when new is executed, obj. constructor is obj. _ PROTO _. constructor, obj. _ PROTO _ = Y. Prototype;
Therefore, obj. constructor is actually Y. Prototype. constructor instead of Y,
Therefore, the object constructor is essentially an object prototype constructor. when the constructor does not point to itself, obj. constructor is not a constructor pointing to the object, but a prototype constructor of the object.
2. object constructor repair
However, there is a small problem. Check the attributes of Y:
Console. Log (obj. y );//99Console. Log (obj. _ PROTO _. y );//Undefined
Since the y attribute does not come from the prototype chain, it naturally comes from the object constructor, but the P function does not define the y attribute,
From the perspective of "inheritance chain" formed by "class inheritance", P is only the source of "inheritance chain", that is, the top-level "base class ", OBJ object instance construction comes from the "subclass" y function,
This is a crack between "analog class inheritance" new and "prototype inheritance" prototype in the JS Object Inheritance System,
Many people are persistently repairing this crack, so they have the constructor to fix it.
By default, a function fun is declared, with fun. Prototype. constructor === fun, so:
OBJ. constructor = y;//Fix the constructor and assign a constructor attribute to overwrite the constructor on the inheritance chain.Console. Log (obj. hasownproperty ('Constructor '));//TrueConsole. Log (obj. constructor );//YConsole. Log (obj. _ PROTO _. constructor );//P
// Or the following constructor Processing Method
VaR fun = (function (){
VaR F = function (){
This. A = 1;
};
F. Prototype = {
Constructor: F,// The constructor is the function f, because an object is directly assigned to F. prototype. The constructor of the object constructed by fun is the constructor of the object, that is, the object function.
Method1: function (){
Return this.;
}
};
Return F;
})();
VaR OBJ = new fun ();
3. If OBJ instancof fun is true, it does not mean that fun must be the constructor of the OBJ object. Fun may not exist in the inheritance chain of OBJ:
X. Prototype =Pro; console. Log (OBJInstanceofX );//TrueConsole. Log (obj. X );//Undefined, X is not the OBJ ConstructorConsole. Log (OBJInstanceofY );//TrueConsole. Log (obj. y );//99
4. Object. Create ()
The new ecmascript version extends some methods for object objects,
Object. Create (Pro) can create an object for the prototype based on Pro. The effect is equivalent
VaRF =Function() {}; F. Prototype=Pro;VaROBJ =NewF ();
// Try: Function P (){ This . P = 11 ;} Function K (){ This . K = 22 ;} Function F (){ This . F = 33;} VaR Pro = New K (); p. Prototype = Pro; VaR O = New P (); VaR OBJ = Object. Create (o); console. Log (O, OBJ ); // All are {P: 11, K: 22} Console. Log (obj. constructor ); // K Console. Log (obj. _ PROTO _. constructor ); // K Console. Log (OBJ Instanceof P ); // True Console. Log (OBJ Instanceof K ); // True Console. Log (OBJ Instanceof F ); // False F. Prototype =Pro; console. Log (OBJ Instanceof F ); // True
5. Object and function:
Console. Log (FunctionInstanceofObject );//TrueConsole. Log (ObjectInstanceofFunction );//True
Do I have a function first or an object first? The following phenomenon may explain that an object is the "top-level" object.
console. log (object. _ PROTO __. _ PROTO __= = function. prototype ); // false console. log (function. _ PROTO __. _ PROTO _ = object. prototype ); // true console. log (object. prototype. _ PROTO __); // null, the object prototype is nvwa-level.