function A() { this.do=function() {return ‘foo’;}; } A.prototype=function() { this.do=function() {return ‘bar’}; }; var x=new A().do();
x 的值是:
有A.prototype.do吗显然没有,于是又开始到实例上找有do方法吗
首先这道题奇奇gaygay的,因为如果想要考察:
实例对象上不存在的属性和方法要去原型上查找
这点的话,应该像下面这样:
function A() {
// this.do=function() {return 'foo';};
}
A.prototype={ //原型对象的对象字面量表示
do:function(){
return 'bar';
}
}
var x=new A().do();
alert(x); //bar
但是如果像题里那样写:
function A() {
// this.do=function() {return 'foo';};
}
A.prototype=function() {//等于个函数了...
this.do=function() {return 'bar';};
};
var x=new A().do();
alert(x);//报错TypeError: (intermediate value).do is not a function
我不知道这是不是重写原型什么的,但是如果像题目这样写,至少你得调用一下A.prototype(),这样返回bar的do方法才会绑定到A.prototype上吧,但是你见过A.prototype()吗?我反正没见过。
所以这道题里如果function A()里没有this.do就是报错,有就是返回foo
实际上本题的答案很简单,首先调用时会先在自身实例上找方法,恰好本身就有 do 方法,所以本身就不会再往原型上找了,所以可以直接得到答案是foo
但是题目中牵扯出来的一些知识点觉得还是要梳理一下比较好,当然也有借鉴评论区其他大佬的讲解
JS专项练习
原型与原型链相关知识点,此部分不太熟悉的同学可以看本人笔记 --> JavaScript进阶笔记的原型链部分
重写原型对象会切断现有原型与任何之前已经存在的实例之间的联系,他们引用的仍然是实例化时的原型,这部分比较绕,可以看图例
题目中重写方式其实是还是很奇怪的,通常我们都是 A.prototype.do=function() { } 这样修改原型对象的,而不是直接将原型给直接赋成函数
- 实际上本题的答案跟上方是否重写没有很大关系,因为首先调用时会先在自身实例上找方法,恰好本身就有 do 方法,所以本身就不会再往原型上找了,所以可以直接得到答案是foo
- 但也是恰好是因为实例上有此属性方法(do),那如果没有呢?那他就会往上的原型对象找,但此时原型对象已经被赋值为一个函数,所以会找不到然后报错.
- 如果想要调用 prototype 上写的方法 应该这样调用 new A.prototype().do()
A.prototype=function() {this.do=function() {return ‘bar’};};
var x=new A.prototype().do() //"bar"
var x=new A();
console.log(x.__proto__); //x.__proto__==A.prototype,打印出来的是一个方法,而不再是一个原型对象console.log(x.__proto__.do()) //报错
function A() {
this.do=function() {return 'foo';};
}
A.prototype=new function() {
this.do=function() {return 'bar'};
}; //使用new,构造函数
var x=new A();
console.log(x.__proto__);console.log(x.__proto__.do())
function A() {
this.do=function() {return 'foo';};
}
A.prototype = function() {
this.do=function() {return 'bar'};
};
var x=new A().do(); // foo
// 如何输出bar
function A() {
this.do=function() {return 'foo';};
}
A.prototype = {
do2 : function() {return 'bar'}
};
var x = new A().do2(); // bar