我想知道,在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 ?
我做了一些研究,但找不到正确的解释。
答案 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
属性。