首页 > 试题广场 >

以下代码执行后,a.x 和 b.x 的结果分别为()

[单选题]
以下代码执行后,a.x 和 b.x 的结果分别为()
function A(x){
  this.x = x;
}
A.prototype.x = 1;

function B(x){
  this.x = x;
}
B.prototype = new A();
var a = new A(2), b = new B(3);
delete b.x;


  • 2, 3
  • 2, 1
  • 2, undefined
  • 其他几项都不对
b的prototype=new A,想错的可能都认为构造函数的x没有赋值就自动去原型下找,错了,
如果构造函数没有x才会去原型下找,
如果有x但是没有赋值,则是undefined,相当于x=undefined.就不会进入原型链了

编辑于 2020-11-05 13:19:47 回复(8)
function A(x){
this.x = x;
}
A.prototype.x = 1;

function B(x){
this.x = x;
}
B.prototype = new A();
var a = new A(2), //a.x首先要在自己的构造函数中查找,没有采取原型上找,这里有this.x = x.所以a.x = 2;
b = new B(3);//B.prototype = new A();形成原型链
delete b.x;//但是delete只能删除自己的x不能删除父级的x.   
//b.x通过原型链找到构造函数A里面的this.x=x但是没有赋值,所以undefined
编辑于 2020-01-30 21:39:49 回复(2)
function A(x){
this.x = x;
}
A.prototype.x = 1; //将A的prototype.x赋值为1
//什么是protytype,也就是JS中的原型链机制,当读取A中的x时,如果A中找不到,则通过原型链去查找X
//在去new一个对象的时候会继承这个原型链
function B(x){
this.x = x;
}
B.prototype = new A();
//将B的原型链指向A,也就是B.prototype = {x:undefined}
var a = new A(2), b = new B(3);
delete b.x;
//最后结果中a.x,可以直接取到
//而b.x原本为3后来被删去,则进入原型链查找,为undefined

发表于 2020-11-28 16:55:27 回复(0)
查找a.x的过程:
a变量指向new A(2)对象,开始在此对象中查找属性x,找到x,直接返回值2,搜索停止。
查找b.x的过程:
b变量指向new B(3)对象,在该对象中确实曾经存在过属性x(值为3),但是在delete b.x;执行完之后存在于实例对象上的属性x就被delete操作符完全删除掉了,此时在实例中查找属性x并不存在,会继续沿指针进入构造函数B指向的原型对象new A()中,此对象中的x因为没有传入实参,赋值为undefined,因此在b.x最后在原型对象中找到了变量x,并将值undefined返回,搜索停止。

运行一下代码检验一下结果

console.log(a.x); // 2 
console.log(b.x); // undefined 

写了一篇此题的分享,有需要可以看看,如有错误请指正:https://blog.csdn.net/weixin_42118462/article/details/121923020

编辑于 2021-12-14 12:53:40 回复(0)
function A(x){
this.x = x;
}
A.prototype.x = 1;

function B(x){
this.x = x;
}
B.prototype = new A();   
var a = new A(2), b = new B(3);
delete b.x; //这里删除了B实例的x,会在原型链中找即 new A() 的存在x且是andefined,并不会接着想上找到A.prototype.x = 1


发表于 2019-12-11 17:50:40 回复(0)
function A(x){ //构造函数A
  this.x = x;
}
A.prototype.x = 1; //A.prototype = { x: 1 }
 
function B(x){//构造函数B
  this.x = x;
}

B.prototype = new A(); //B.prototype = { x: undefinded }
                       //如果new A()传入参数,那么x才不会是undefinded

var a = new A(2), // a = { x: 2 }
    b = new B(3); // b = { x: 3 }
delete b.x;//删除掉对象b下的x属性,那么 b = { }

//以上过程结束后:
// a.x = 2
// b.x 先去b = {}里找,没有的话去 b的构造函数的原型 里找,
// 也就是B.prototype = { x: undefinded } 里面找
// 可得 b.x = undefinded

发表于 2022-01-28 11:18:10 回复(0)

本人对于所遇面试题进行了详细的知识点拆解与梳理,在此分享给大家,有错欢迎指出讨论,求共同进步 --> JavaScript专项练习

知识点梳理
  • 原型与原型链相关知识点,此部分不太熟悉的同学可以看本人笔记 --> JavaScript进阶笔记的原型链部分
  • 如果有x但是没有赋值,则是undefined,相当于x=undefined. 就不会进入原型链
答案解析
function A(x){
   this.x = x;
}
A.prototype.x = 1; //将A原型上的x设置为1
function B(x){
   this.x = x;
}
B.prototype = new A(); //将B原型上的x设置为 A的一种object. 所以B实例出来object的prototype就是{x:undefined}
var a = new A(2),//a.x首先要在自己的构造函数中查找,没有采取原型上找,这里有this.x = x.所以a.x = 2;
   b = new B(3);//此时 b.x = 3 ;但是因为上面[B.prototype = new A()],所以形成原型链,其父级prototype={x:undefined}
delete b.x; //删除实例b上的[x]属性,但是delete只能删除自己的x不能删除父级的x. 
console.log(a.x,b.x)
  • var a = new A(2) 很容易理解,就是 a.x==2
  • 看上面代码可以得知,在进行到 b = new B(3) 这步的时候 b的原型 prototype={x:undefined}
  • delete b.x; 删除实例b上的[x]属性,但是delete只能删除自己的x不能删除父级的x. 所以我们查看b.x时会走到b的原型上就是 {x:undefined} 这里也是很容易踩到的陷阱,只要有这个属性,即便是undefined也不会在原型上再往上找了
陷阱:

选择 2, 1 选项的同学就是踩到陷阱咯

  • B的prototype=new A(), 想错的可能都认为构造函数的 [ x ] 没有传值进去,this.x赋值为undefined, 所以还会去A的prototype原型上找,找到 x = 1 -->错误
  • 实际上是:如果构造函数 没有x 才会去原型下找
  • 如果有x但是没有赋值,则是undefined,相当于x=undefined. 就不会进入原型链了
编辑于 2021-10-25 13:11:50 回复(0)
JS的每一个function都有一个prototype属性 ,该属性指向一个普通的Object。由这个function new出来的每一个实例都会带上一个__proto__的指针,指向prototype指向的那个Object。当把类的方法放到function的prototype里的时候,该prototype对象就会添加一个新的属性,那么每个实例都会获得该类的方法。
这就是基本的封装。即类的属性在构造方法里定义,类的方法在prototype里添加。
那为什么在原型上添加的方***被类的对象引用呢?
因为JS首先在该对象上查找方法,如没有则会去原型上查找。直到查找到Object跟类。


发表于 2019-09-13 19:39:09 回复(1)
一开始不会做,看到各位大佬的解释有些理解,但还有最后一个问题:B的x属性删除后。他为啥不会继续往上找,最终找到A.proprtype.a=1?
求解,这题我先收藏着
发表于 2020-09-12 22:31:20 回复(2)
1)属性先查自身,没有再查构造函数的原型。2)在全局下声明的变量,有var声明的不可以被delete删除,无var声明的可以被delete删除。
发表于 2022-04-05 16:41:16 回复(0)
function A(x) {
    this.x = x;
}
A.prototype.x = 1;

function B(x) {
    this.x = x;
}
B.prototype = new A(); // p的原型是A对象的实例,因为A实例上没有传参x,所以输出undefined
var a = new A(2), b = new B(3);
delete b.x;
console.log(a.x); // 2
console.log(b.x); // undefined
//扩展1
function A(x) {
    this.x = x;
}
A.prototype.x = 1;

function B(x) {
    this.x = x;
}
B.prototype = new A(5); //实例传参
var a = new A(2), b = new B(3);
delete b.x; // 删除了对象本身的3,就去原型上找,找到了new A() 找了5
console.log(a.x); // 2
console.log(b.x); // 5
//扩展2
function A(x) {
    this.x = x;
}
A.prototype.x = 1;

function B(x) {
    this.x = x;
}
B.prototype = A.prototype; // 共享同一原型
var a = new A(2), b = new B(3);
delete b.x; // 删除了对象本身的3,就去原型上找,找到了A.prototype 找了1
console.log(a.x); // 2
console.log(b.x); // 1



发表于 2022-04-04 22:43:50 回复(0)
function A(x){
    this.x = x;
}
A.prototype.x = 1;
 
function B(x){
    this.x = x;
}
 
B.prototype = new A();
var a = new A(2), b = new B(3);
delete b.x;

 var a = new A(2) // A构造函数下有x,所以直接为2
b = new B(3) // b下本来有x,但通过delete b.x被删除了,所以构造函数下没有x了会顺着原型链查找。
B.prototype = new A() // B的原型指向A,A下有x但没有被赋值,所以undefined
发表于 2021-12-18 18:07:39 回复(0)
挺迷惑人的,其中B.prototype = new A();因为new A没传参数所以相当于 B.prototype  = { x : undefine} , b在原型上就先找到的是它。
发表于 2021-09-27 18:48:57 回复(0)
因为B.prototype = new A();那么B.prototype的属性就已存在一个x值,只是是undefined,因此若其实例化出来的对象上无值,那么按照原型链的查找,就会得出x为undefined了
发表于 2020-03-10 14:03:49 回复(2)
抄笔记-delete b.x也就是删了b对象中名为x的属性,那它只能去b的原型链中找了,因为B.prototype = new A(),x没赋值所以为undefined。如果再delete b.__proto__.x那就再去下一层原型链中找,就是A.prototype.x = 1,b.x = 1
发表于 2023-04-20 09:39:34 回复(0)
a.x因为new A产生一个新对象,所以是2,因为new A产生的是不同的空间,没new一次就会有新的空间。第一次B.prototype就是一个空的对象,后来new A就是另外一个新的对象 ,因此并不会覆盖B的原型对象,new B产生b,然后删除b.x,即b是个空对象,然后查找b.x看自己没有,然后去原型上查找,原型上又是一个空对象,所以b.x是undefined
发表于 2022-11-07 14:43:08 回复(0)
b 没有原型,它的 x 删掉之后,自然 b.x 输出 undefined。
发表于 2023-02-12 11:30:54 回复(0)
new A()构造新的实例对象时虽然没有传值,但是构造函数中的this.x = x已经执行了,没有传值则x=undefined,所以this.x=undefined,则不会再向原型链中找x的值
发表于 2022-07-09 09:59:34 回复(0)
首先,B.prototype = new A()这一行代码表示:
    1. new 了一个A的实例,但是没有携带参数,所以 new A()的结果即为 { x: undefined }
    2. 然后让B的原型指向上面的实例对象 { x: undefined }
然后,执行 a = new A(2), b = new B(3)
    1. a = new A(2),又创建了另一个A的实例,此时携带参数,即 a = { x: 2 },所以 a.x  = 2
    2. b = new B(3), 创建了一个B的实例,也携带参数,即 b = { x: 3 }
最后,执行 delete b.x,删除了 b 实例身上的 x 属性,但不会删除原型身上的属性(此时 B 的原型指向的是实例对象 { x: undefined })
所以访问 a.x 时,结果为2,访问 b.x 时,由于自身实例上没有了 x 属性,就会沿着原型链向上寻找,发现 b 的原型 { x: undefined } 上有 x 属性,且值为 undefined,故结果为 undefined
发表于 2022-04-12 09:39:33 回复(1)