首页 > 试题广场 >

请按顺序写出打印结果,并说明原因。 var name =

[问答题]

请按顺序写出打印结果,并说明原因。

var name = 'global';
var obj = {
    name: 'local',
    foo: function(){
        this.name = 'foo';
    }.bind(window)
};
var bar = new obj.foo();
setTimeout(function() {
    console.log(window.name);
}, 0);
console.log(bar.name);
 
var bar3 = bar2 = bar;
bar2.name = 'foo2';
console.log(bar3.name);

            var name = 'global';
            var obj = {
                name: 'local',
                foo: function(){
                    console.log(this)
                    this.name = 'foo';
                }.bind(window)
            };
            console.log(obj.foo());// 此时调用的this是window
            // 由于new绑定的优先级大于bind绑定,所以函数内部this还是obj {}
            var bar = new obj.foo();
            console.log(bar);//{name:'foo'}
            console.log(window.name);//global
            
            // 定时器任务,在最后放入任务队列,window对象没有被改变,所以输出 'global'
            setTimeout(function() {
                console.log(window.name);
            }, 0);
            // 此时bar.name =foo,因为被赋值了
            console.log(bar.name);
              
            // 此时执行顺序是var bar3,bar2=bar,bar3=bar2, 所以bar3/bar2/bar都是指向同一个对象
            var bar3 = bar2 = bar;
            bar2.name = 'foo2';
            // 所以bar2修改属性,bar3的也改变了,此时输出为'foo2'
            console.log(bar3.name);
发表于 2020-03-06 23:02:18 回复(8)
'foo'  //bind返回一个函数,该函数体中的this绑定到window上,然后new对该函数进行构造调用,返回一个新对象,函数体中的this指向该对象。bind是硬绑定,new绑定的优先级高于硬绑定。所以this还是绑定在bar这个新对象上。this.name='foo'就是bar.name='foo'
'foo2'  //复杂类型值地复制是引用复制,bar3、bar2和bar指向的都是同一个对象,所以bar2.name='foo2'对对象的熟悉进行修改时,bar3和bar的数据同样收影响
'global'  //setTimeout设置一个定时器,定时器到时后调用回调函数,但定时器到时后只能将回调的执行放到事件队列的末尾,不能插队,所以console.log(window.name)这条输出语句是最后执行的


发表于 2020-03-09 21:49:20 回复(0)
Event Loop参见https://segmentfault.com/a/1190000016278115,我觉得写得很好。
发表于 2020-03-11 22:47:39 回复(2)
foo
foo2
global
主要是这句 var bar = new obj.foo()
这涉及到隐性绑定,硬绑定和new绑定
new绑定会使得this不管之前绑定了什么,this都会绑定给new的对象上
所以bar.name = this.name = ‘foo’
var bar3 = bar2 = bar复制的是bar地址
所以bar2修改name就是修改了this.name
所以bar3.name = ‘foo2’
setTimeout()不管什么时间都会最后出来

发表于 2020-04-22 19:00:28 回复(1)
1. window.name = 'global'
2. 执行new,bar.name = 'foo'
3. 输出 foo
4. 直接赋值,bar.name = bar3.name = 'foo2' 输出 foo2
5. settimeout global

new绑定 > 显式绑定 > 隐式绑定 > 隐式绑定
编辑于 2023-06-10 21:46:33 回复(0)

new绑定优先级高于bind

发表于 2022-08-18 19:01:35 回复(0)
明明是硬绑定跟new 绑定this的优先级问题,咋说道操作符优先级去了
发表于 2020-10-16 11:11:58 回复(0)
foo
foo2
global

第八行使用obj的foo函数作为构造函数创建一个对象,构造函数foo将该对象中的name字段设置为字符串"foo"
9行setTimeout打印window.name的值,进入微任务队列,尚未执行
12行打印bar对象的name字段,为"foo"
14行创建bar2和bar3引用,并一同指向bar所指向的对象
15行将bar2的name字段修改为'foo2',因为指向的对象相同,所以bar,bar3的值也会一并修改
16行打印bar3的值,为"foo2"
代码全部结束之后setTimeout设置的任务运行,打印window.name,为”global“
发表于 2020-07-03 21:03:52 回复(0)
说白了就是个优先级问题,这些答案一个也没有说道点子上。感谢木子凡凡。
这里的new是无参数new。优先级是18,而成员访问优先级是19,
又因为无参数new是从右往左执行,所以是 先执行 obj.foo  然后执行new。

发表于 2020-05-03 13:46:04 回复(0)
foo
undefined
foo2

//首先声明了一个obj对象,里面有一个name属性,和一个foo函数对象
//而bar是用foo作为构造函数创建的一个对象,但这个构造函数因为用bing函数将this->window,
//所以创建的bar对象中并没有name属性,而是定义了window.name='foo'

//bar3和bar2是引用类型数据,且都指向了bar对象内存,
//bar2.name='foo2'将该内存中的name属性值改为了'foo2'
//由于bar3也指向了同一内存,所以取bar3.name也为'foo2'
发表于 2020-04-03 22:00:57 回复(0)
global     foo     foo
发表于 2020-03-23 22:25:06 回复(0)