首页 > 试题广场 >

function A() { this.do=fun

[单选题]

function A() {
    this.do=function() {return ‘foo’;};
}

A.prototype=function() {
    this.do=function() {return ‘bar’};
};

var x=new A().do();

x 的值是:
  • bar
  • 报错
  • foo
  • undefined
推荐
只有实例对象上不存在的属性和方法才会去原型上查找
编辑于 2017-03-19 12:07:15 回复(10)
为什么错误的答案解析会有那么多人点赞!!!?
//这种是原型的重写第一种 没实例化重写原型
function Person(){};
Person.prototype = {
add :function(){
alert(this.name);
},
name :"aty"
}
var p2 =new Person();
p2.add();//aty 不报错 不信你们可以敲一下代码
原因:重写原型对象切断了现有原型与任何之前
已经存在的实例之间的联系,他们引用的仍然是最初的原型
我们仔细看看这句话,我们并没有在重写原型之前实例化,所以对于实例p2来说 这里依然是相对最初原型
//第二种原型重写 也就是先实例化再重写原型
function Person(){};
var p2 =new Person();
Person.prototype = {
add :function(){
alert(this.name);
},
name :"aty"
};
p2.add();//error
//这里会报错 原因:重写原型对象切断了现有原型与任何之前
已经存在的实例之间的联系,他们引用的仍然是最初的原型
function A() {
this.do=function() {return ‘foo’;};
};
A.prototype=function() {
this.do=function() {return ‘bar’};
};
var x=new A().do();
//很显然这里是第一种而不是第二种 这个时候你是不是在想
为什么是 "foo",不是"bar"呢,你看看
原型上的方法一般怎么写 是A.prototype.方法名
如A.prototype.show=function(){},然后再通过
再通过实例.show()才可以调用,这里直接将原型重写成一个函数
就算修正了constructor,也没有用,
2019-2-21: 14:36 更正 如下内容
有A.prototype.do吗显然没有,
于是又开始到实例上找有do方法吗
--------------------分割线-----------------------
此处应为  实例上有do 方法吗  
有的 所以返回"foo"
编辑于 2019-02-21 19:30:26 回复(13)
发现没有一个人答到点子上啊,这个地方原型被重写了,应该重新指定下constructor,或者这样定义:
A.prototype.do=function() {  }
否则,即便这里方法不重名,也无法访问到原型上的方法
发表于 2017-05-03 10:55:00 回复(8)
首先从自己的实例对象里面找该属性,找到了就不用再向上继续查找了。
发表于 2017-04-09 21:53:54 回复(1)

  首先这道题奇奇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

发表于 2018-05-28 09:17:31 回复(1)
1.new A()——创建了一个空对象且空对象的原型指向A.prototype。
2.function A(){this.do=function() {return ‘foo";};}——使用this在新创建的空对象上添加了do方法
3.A.prototype=function() {
    this.do=function() {return "bar"};
};——改变了A.prototype的值,值为function(){this.do=function(){return "bar"}; 
注:并没有在原型上添加do方法

4.new A().do()时调用生成的对象上自身拥有的do()方法

如上图所示,var y=new A();后产生的对象本身就拥有do方法 function(){return "foo"};

所以调用do方法时会输出"foo"
发表于 2020-07-12 18:16:57 回复(0)
重点应该是原型重写与修改之间的区别,像这篇文里写的 https://blog.csdn.net/Beng_shakalaka/article/details/78379098
发表于 2018-08-16 12:23:52 回复(0)

实际上本题的答案很简单,首先调用时会先在自身实例上找方法,恰好本身就有 do 方法,所以本身就不会再往原型上找了,所以可以直接得到答案是foo

但是题目中牵扯出来的一些知识点觉得还是要梳理一下比较好,当然也有借鉴评论区其他大佬的讲解
JS专项练习

知识点梳理
  • 原型与原型链相关知识点,此部分不太熟悉的同学可以看本人笔记 --> JavaScript进阶笔记的原型链部分

  • 重写原型对象会切断现有原型与任何之前已经存在的实例之间的联系,他们引用的仍然是实例化时的原型,这部分比较绕,可以看图例图片说明

  • 题目中重写方式其实是还是很奇怪的,通常我们都是 A.prototype.do=function() { } 这样修改原型对象的,而不是直接将原型给直接赋成函数

答案解析
  1. 实际上本题的答案跟上方是否重写没有很大关系,因为首先调用时会先在自身实例上找方法,恰好本身就有 do 方法,所以本身就不会再往原型上找了,所以可以直接得到答案是foo
  2. 但也是恰好是因为实例上有此属性方法(do),那如果没有呢?那他就会往上的原型对象找,但此时原型对象已经被赋值为一个函数,所以会找不到然后报错.
  3. 如果想要调用 prototype 上写的方法 应该这样调用 new A.prototype().do()
编辑于 2021-10-25 13:14:44 回复(0)
1. 题目中由于A()构造函数中已经存在了do()方法,所以不用再到原型上去找do,并且就算是去原型上找do方法也是找不到的。
原因是:
A.prototype=function() {
    this.do=function() {return ‘bar’};
};
将A的原型重写成了一个函数,如果想要调用到A.prototype中的do,至少是要执行一次A.prototype()的
所以希望在这种定义下打印出"bar",这样写可以实现,但是感觉没什么意义
var x=new A.prototype().do()   //"bar" 
2. 为了更好说明原型上也不存在do,再换一种写法
var x=new A();
console.log(x.__proto__);           //x.__proto__==A.prototype,打印出来的是一个方法,而不再是一个原型对象
console.log(x.__proto__.do())    //报错
其实,不仅仅是说不能再在原型上找到do,就连正常的原型对象都不存在了

3.如果想要定义原型上的方法,
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())


发表于 2019-01-02 20:46:23 回复(0)
发表于 2018-06-04 21:24:55 回复(4)
C
发表于 2017-02-09 15:38:31 回复(0)
构造函数中的this永远指向它的实例,所以返回值是foo的方法是实例身上的。返回值是bar的方法实在显示原型身上,实例也能获取到,不过实例自身已经有了这个方法就用自己的。所以返回foo
发表于 2022-07-20 21:41:30 回复(0)
A.prototype被设置为等于一个对象字面量创建的新对象,他的constructor不再指向A,需要回复constructor。这里的x的constructor == A,所以选foo
发表于 2022-04-12 11:04:47 回复(0)
先找实例对象上的方法,再找原型链上的方法
发表于 2021-10-13 00:37:53 回复(0)
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
编辑于 2019-03-31 22:37:41 回复(1)
先在实例对象中找,找到了则使用,找不到则在实例对象__proto__对应的构造函数prototype原型中找,找到使用,找不到报错
发表于 2018-07-09 16:36:18 回复(0)
只有实例对象不存在的方法才会去原型找
发表于 2018-05-08 00:02:56 回复(0)
// Ewarm朋友答到了点上,除了最后查找顺序说反了;下面是补充之前让我疑惑的this.do
function A() { 

}

function proto() {
    this.do=function() {return 'bar'}; // 这样只是给函数增加了一个自定义属性
};

A.prototype= new proto();  // 而函数的自定义属性必须通过其实例才能访问
var x=new A().do(); // "bar"

编辑于 2017-12-25 14:51:25 回复(1)
我是这样理解的var x=new A().do();
new A().do()调用的是a函数的私有方法do,然后调用后返回了foo字符串
将字符串赋值给x,所以最后是foo
编辑于 2017-06-06 12:03:55 回复(0)
C,验证了一下是这样的
发表于 2017-02-09 20:11:24 回复(0)
foo
发表于 2017-02-05 11:26:26 回复(0)