3

我想知道,new在 JavaScript 中使用运算符创建对象时变量的范围是什么?

function A(){
   this.a = 1; // instance property
}

function B(){ 
   this.a = 3; // instance property
}

案例1:我明白这一点

// assign again prototype a property as 2 
A.prototype.a = 2 ;// prototype property

var obj = new A();

console.log( obj instanceof A );
console.log( obj.a == 1 ); 

案例 2:将 A 构造函数更改为 B 引用

A.prototype.constructor =  B;
A.prototype.a = 2 ;// prototype property


var obj = new A();
console.log( obj instanceof B ); // false, as I expected
console.log( obj.a == 1 ); // still 1 why ?

案例3: 继承范围

A.prototype = new B();
A.prototype.a = 4 ;// prototype property


var obj = new A();
console.log( obj instanceof B ); // true , as I expected
console.log( obj.a == 1 ); // still 1 why ?

我做了一些研究,但找不到正确的解释。

4

2 回答 2

5

在对象初始化代码运行之前原型分配/绑定到对象

> function A() { console.log(this.a); this.a = 1; console.log(this.a); };
undefined
> new A();
undefined
1
A {a: 1}
> A.prototype.a = 2;
2
> new A();
2
1
A {a: 1, a: 2}

在函数初始化代码中,在分配 Aa 的原型之前,第一个 console.log 是未定义的。在原型 Aa 被分配后,第一个 consol.log 正确显示为 (2) 然后 this.a 被分配为 1,第二个 console.log 正确显示为 (1)

于 2013-07-11T13:43:20.727 回答
4

仅当在对象本身上找不到自己的属性时才查找原型链。在您的所有示例中,实例都有一个a属性,在其构造函数中定义。

在情况 2 中,如果您不希望obj成为 的实例B(并且它不是,B从未被调用),您为什么希望obj.a成为1?它与您的案例 1 完全相同,唯一的区别是obj[[Prototype]] 具有误导性的构造函数属性。

案例3也是同样的事情。基本上,您的所有示例都是相同的,obj.a是在构造时定义的,并且会隐藏对象原型链中的任何同名a属性。

于 2013-07-11T13:44:43.600 回答