首页 > 试题广场 >

以上代码,在浏览器中执行的结果是

[单选题]
var A = {n:4399};
var B = function(){this.n = 9999};
var C = function(){var n = 8888};
B.prototype = A;
C.prototype = A;
var b = new B();
var c = new C();
A.n++;
console.log(b.n);
console.log(c.n);

以上代码,在浏览器中执行的结果是
  • 9999 8889
  • 10000 8888
  • 4400 8889
  • 9999 4400
  • 4400 4400
推荐
console.log(b.n);
在查找 b.n 是首先查找 b 对象自身有没有 n 属性,如果没有会去原型(prototype)上查找
当执行 var b = new B() 时,函数内部 this.n=9999(此时this指向b) 返回b对象,b对象有自身的n属性,所以返回 9999
console.log(c.n);
同理
当执行 var c = new C() 时,c对象没有自身的n属性,向上查找,找到原型 (prototype)上的 n 属性,因为 A.n++(此时对象A中的n为4400), 所以返回4400

编辑于 2017-01-09 19:41:20 回复(21)
var c = new C();

上面这个语句的实际运行过程是这样的。

var c = function() {
    var o = new Object();
    //第一个参数改变函数的作用域,即相当于在函数内部设置this = o
    C.apply(o, argumens);
    return o;
}

这样,由于C()函数中

var n = 8888;

这样只是在函数中创建了一个私有变量,并没有为对象执行任何操作,因此C的实例中不存在名字为“n”的属性。所以,c.n会访问原型中的属性名为“n”的值。

编辑于 2017-02-20 17:18:44 回复(5)
new运算的具体执行过程:
    1)创建一个空对象
    2)把这个空对象的__proto__指向构造函数的prototype
    3)把这个空对象赋值给this
    4)执行构造函数内的代码,注意此时的this指向新对象,this.n=9999 等价于b.n=9999;
然后访问b.n,存在,直接输出b.n。
再去访问c.n,不存在,通过原型链__proto__向上寻找,c.__proto__指向C.prototype也就是A,所以就是输出A.n
发表于 2017-05-03 19:20:05 回复(3)
        var A={n:4399};
        var B=function(){
            this.n=9999
        }    
        var C=function(){
            var n=8888
        }
        B.prototype=A;
        C.prototype=A;
        var b=new B();
        var c=new C();
        A.n++;
        console.log(b.n);
        console.log(c.n);
  1. 首先改写了B和C的原型,他们的原型对象都指向A,因此,它们的原型都拥有属性n:4399
  2. 通过new创建了B和C的实例,用这种方式调用构造函数经历四步
  •   创建一个新的实例对象;b,c
  • 将构造函数的作用域赋值给新对象(this指向新对象b,c);  此时B中的this指向实例对象b,即b.n=9999;
  • 执行构造函数中的代码;给实例添加属性,此时执行b.n=9999,为b添加实例属性;执行var n=8888,对实例c没有影响
  • 返回新对象 ;返回实例对象b,拥有实例属性n=9999,通过原型链,具有原型属性n=4399;返回实例对象c,只有原型属性 n=4399
  1. 然后改写原型的属性A.n,因为原型上的属性是公用的,所以b和c中原型上的n属性都为4400,b还有实例属性n=9999。由于查找属性的时候现在实例上找,再去原型中找,只要找到了就不往后找了。于是b.n=9999(在实例中找到),c.n=4400(在原型中找到)
编辑于 2018-05-17 14:53:21 回复(8)
这道题本质上是一道原型链的继承问题。B和C都继承了A的属性,而b是B的实例,当查找b的n属性时,在B 的原型中找到了n=8999;c是C的实例,在C的原型中没有n属性,只有局部变量n,所以沿着原型链找到了A的n属性4399+1,即4400.
发表于 2017-03-16 16:47:06 回复(0)
var A = {n:4399};  //A是一个对象

var B = function(){this.n = 9999};   
      //B是一个构造函数,这个函数里有一个属性n,因为用了this.n

var C = function(){var n = 8888};    
      //C是一个构造函数,这个函数里只是定义了一个局部变量n,
      //这个局部变量n并不属于函数自身的属性
  
B.prototype = A; //prototype是原型,原型的本质也是一个对象。
      //现在让B的原型对象指向了A这个对象。此时B的原型对象就是对象A。
  
C.prototype = A; //prototype是原型,原型的本质也是一个对象。
      //现在让C的原型对象指向了A这个对象。此时C的原型对象也是对象A。
  
var b = new B(); //通过new关键字创建了一个实例化对象b, 注意b的本质是一个对象。
      //构造函数的属性都是这个对象的属性。
      //因为构造函数B里有一个属性n,故此时 b = {n:9999}
  
var c = new C(); //通过new关键字创建了一个实例化对象c,注意c的本质是一个对象。
      //构造函数的属性都是这个对象的属性。
      //因为构造函数C里没有任何属性,古此时 c = {}
  
A.n++;
console.log(b.n); //b.n 首先会去b对象里找n,b对象里如果有n就直接获取,
      //如果没有就去  b对象的构造函数的原型对象 里找
      //因为b = {n:9999},所以b对象是有属性n的,故直接获取b.n = 9999
  
console.log(c.n); //c.n 首先会去c对象里找n,c对象里如果有n就直接获取,
      //如果没有就去  c对象的构造函数的原型对象 里找
      //因为c = {},所以c对象没有属性n,
      //只能去 c对象的构造函数的原型对象(也就是A={n:4399})里找
      //而倒数第三行执行了 A.n++; 故 A.n的值变成了4400, 所以c.n就是4400

编辑于 2022-01-08 19:07:27 回复(0)
this.n 说明这个n是b实例创建的 ,  对象b实例和b继承的函数C原型中都有n属性 , 优先查找b实例中的n属性 .
b==B.prototype  但是  b != B
同理
c==C.prototype  ,  c !=C
函数C中var n=8888并不在原型中 , 所以对象c.n无法找var n=8888 , 只在函数C的_proto_原型中找到了n:4400
编辑于 2018-08-15 10:26:47 回复(0)
console.log(b.n); 在查找 b.n 是首先查找 b 对象自身有没有 n 属性,如果没有会去原型(prototype)上查找 当执行 var b = new B() 时,函数内部 this.n=9999(此时this指向b) 返回b对象,b对象有自身的n属性,所以返回 9999 console.log(c.n); 同理 当执行 var c = new C() 时,c对象没有自身的n属性,向上查找,找到原型 (prototype)上的 n 属性,因为 A.n++(此时对象A中的n为4400), 所以返回4400
发表于 2017-03-07 19:31:34 回复(0)
请问有没有人解释下:  函数内的私有变量无法访问,
var C = function(){var n = 88888;}
我是不是可以理解为函数内的局部变量只能同过闭包获取,其他方式无法访问
发表于 2018-11-10 15:48:52 回复(0)
D
都是向原型链发起查找
a是在自己的实例对象里找到了n属性,就不必再向上查找;
c是在自己的实例对象里没有属性n导致原型链上查找
发表于 2017-01-11 12:15:51 回复(0)
C中的 var 定义的变量没有绑定在C对象上,仅仅作为构造函数中的局部变量
发表于 2020-07-31 08:31:47 回复(0)
执行new 构建对象时,只有里面的this会被绑定都新建对象
发表于 2017-08-18 22:09:19 回复(0)
原型链原理
首先从自己的实例对象里面找该属性,找到了就不用再向上继续查找了

发表于 2017-01-17 11:37:56 回复(0)
D
------
B,C的原型对象都是A,但是B的构造函数中,n的更改是在B所构造的对象上的,而不是B的原型对象(即A)。

发表于 2017-01-04 13:18:19 回复(0)
  • b.n --> n 属性在对象自身上存在
  • c.n --> n 属性在对象的原型上存在

发表于 2022-08-07 12:02:39 回复(0)
我也错了, 试了一下, 大概可以解释的通
举个例子
let F = function(){
    let num1 = 1;
    this.num2 = 2;
}
let f = new F();
console.log(f);
// F {num2: 2}
// 这里控制台的输出找不到num1的半点影子
可以比作c语言中的类, F就是一个类, function(){let num1.........}等是他的构造函数
那么此处的let num1 = 1; 只是在构造函数中声明了一个变量, 构造函数执行完了, num1就被销毁了, 没有任何作用
而构造函数中的this指向了该实例, 这里也就是f, 也就是说f.num2 = 2; 为对象f创建了一个变量num2, 并赋值为2

另外, prototype也就是现在的 [[prototype]] , 应该是只这个对象继承于谁, Object是所有对象的基类, 所以如果不做任何处理, 自己声明的对象其实这个属性应该是指向Object类
这道题改为了指向A, 

输出c.n时, C的构造函数和我举的例子一样, 只是声明了一个变量, 没啥用, 也就是说b中没有n, 那么就会沿着原型链网上找, 找到了A, A的上一层是Object, A中有n所以不再往上面的Object找, A中的n被改为了4400, 所以c.n输出的是4400
c{
    // 属性
    // 没有自己创建的属性
    // something else
    
    // 上层原型链(c继承了谁)
    [[prototype]]: A{
        n: 4400
        [[prototype]]: Object{
            // something else
        }
    }
    
}

输出b.n时, B的构造函数和我举得例子的num2一样, 为对象b创建了一个新的属性n并赋值为9999(this.n = 9999); 
所以输出b.n时由于b中有n = 9999, 不再找上一层的A.n
b{
    // 属性
    n: 9999
    // something else
    
    // 上层原型链(b继承了谁)
    [[prototype]] : A{
        n: 4400
        [[prototype]]: Object{
            // something else
        }
    }
}

大概就是这样吧, 我也没系统阅读相关书, 看js高级程序设计把前面跳了, 现在自己试了试之后感觉理解了点

发表于 2022-04-19 22:16:06 回复(0)
首先会先去函数内部找。如果找到则返回。没找的则去他的原型prototype里去找
发表于 2021-06-03 22:54:57 回复(0)
  • 首先,一般按照原型链来查询属性,所有C中的var n和原型A的n属于同一个
    • 第二个考点是,原型的属性值修改会影响到所有的子类,但是子类的修改不会影响原型,所以C中的n赋值对A无效,但是A.n重新赋值后,影响了C,c.n=4400
  • 在指定了作用域情况下,不会按原型链查询属性,this.n通过this限定在当前作用域下查询n属性,添加n属性(不能添加的特殊情况大概有两种原因,子类不可扩展,原型属性只读),所以b.n和A.n不是同一个,A.n的修改不会影响b.n。b.n=9999
发表于 2017-12-08 15:10:19 回复(0)
不知道,为什么。直接这么看,有的蒙。贴入编辑器以后。反而清楚一点。可能还不熟悉吧
分解看:①简单的看:
		var A = {n:4399};
		var B = function(){this.n = 9999;}
		var C = function(){var n = 88888;}

		var b = new B();
		var c = new C();

		console.log(b.n);   //9999
		console.log(c.n);  //unsigned(在c的对象上没有属性n)
		var A = {n:4399};
		var B = function(){this.n = 9999;}
		var C = function(){var n = 88888;}
                
               *2 C.prototype = A;
		var b = new B();
		var c = new C();

		console.log(b.n);   //9999
		console.log(c.n);  //43999((在c的对象上没有属性n,但是c的原型上有)
		var A = {n:4399};
		var B = function(){this.n = 9999;}
		var C = function(){var n = 88888;}
                
               *3  B.prototype = A;
                *2  C.prototype = A;
		var b = new B();
		var c = new C();

		console.log(b.n);   //9999(b的原型链上A的的对象上有,但是在b的对象上有属性n)    console.log(c.n);  //43999(在c的对象上没有属性n,但是c的原型链上A的的对象上有)
		var A = {n:4399};
		var B = function(){this.n = 9999;}
		var C = function(){var n = 88888;}
		*3  B.prototype = A;
                *2 C.prototype = A;
                
                var b = new B();
                var c = new C();
		
               *4   A.n++;
              console.log(b.n);   //9999(b的原型链上A的的对象上有,但是在b的对象上有属性n) 
             console.log(c.n);  //43999(在c的对象上没有属性n,但是c的原型链上A的的对象上有,同时a的属性n改变了)

发表于 2017-04-09 21:22:49 回复(0)
new来调用函数属于构造函数调用,会自动执行以下操作:
1.创建/构造一个新对象
2.这个新对象会被执行[[原型]]连接,也就是把这个空对象的__proto__指向构造函数的prototype
3.这个新对象会被绑定到函数调用的this上
4.如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个对象
所以在这里,new C()了之后实际执行了
var c=function(){
var o=new Object()
C.apply(o,arguments)
return o;
}
c.n首先会找自身对象上面有没有,没有再找原型
发表于 2023-10-05 22:06:23 回复(0)
var n...这里的题目真的考眼力
发表于 2023-07-30 10:08:57 回复(0)