基于原型的变量范围,JavaScript中的`new`运算符

时间:2013-07-11 13:32:37

标签: javascript oop

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

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:将构造函数更改为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 ?

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

2 个答案:

答案 0 :(得分:5)

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

> 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}

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

答案 1 :(得分:4)

只有在对象本身找不到自己的属性时才会查找原型链。在所有示例中,实例上都有a属性,在其中定义构造

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

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