Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS 函数 this 相关题目 #20

Open
RookieDay opened this issue Dec 29, 2016 · 10 comments
Open

JS 函数 this 相关题目 #20

RookieDay opened this issue Dec 29, 2016 · 10 comments

Comments

@RookieDay
Copy link

下面这段代码输出结果是?

var length=10;
function fn(){
    console.log(this.length);
}
var obj = {
    length:5,
    method: function (fn) {

        fn(); 
        arguments[0](); 
    }
};
obj.method(fn);
obj.method(fn, 123);
@bichaorui
Copy link

10
1
10
2

@NKnife
Copy link

NKnife commented Dec 29, 2016

把 fn 函数里面代码改成 console.log(this); 就可以知道答案:this 指向执行时的对象。

obj.method(fn); 里,method 方法的 this 指向obj。但是这里只是传入一个 fn 函数的实参,并没有执行 fn 里面的代码块。
在 method 方法里面,执行了 fn 函数。但是这时候 fn 是 window 对象的属性,所以执行时 this 指向了 window。输出 window.length,也就是全局里的变量 length。
arguments[0]() 相当于 (匿名函数).arguments[0]() 。this 指向匿名函数,输出了 (匿名函数).length

所以结果是:

obj.method(fn);                                
//10(全局变量length)    
//1(参数数量)

obj.method(fn, 123);                        
//10(全局变量length)    
//2(参数数量)

@LZ0211
Copy link

LZ0211 commented Dec 29, 2016

var length=10;
function fn(){
    console.log(this.length);
}
var obj = {
    length:5,
    method: function (fn) {
        //fn绑定的上下文是global,this <=> window
        //console.log(window.length)
        fn();
        //fn绑定的上下文是arguments,this <=> arguments
        //即arguments.0=fn
        //console.log(arguments.length)
        arguments[0](); 
    }
};
obj.method(fn);
//>>>10
//>>>1
obj.method(fn, 123);
//>>>10
//>>>2

@FrankFang
Copy link
Collaborator

FrankFang commented Dec 29, 2016

这个题目又一次印证了我的那篇《this到底是什么
arguments[0]()
假象为
arguments.0() // 忽略语法错误,这里只是为了出现点语法
根据「转换代码」将其转换为
arguments.0.call(arguments)

所以里面的 this 就是 arguments 了。

@FrankFang FrankFang changed the title JS 函数调用模式/this 相关题目 JS 函数 this 相关题目 Dec 29, 2016
@hellochenk
Copy link

hellochenk commented Dec 30, 2016

1、声明函数fn,打印出 this 的 长度。
2、声明对象obj,
2.1.属性length 值为 5 。
2.2方法method 第一个参数(这里有点看不懂了;
method内执行外部方法fn()和
arguments()。我认为是method方法中传递进来的fn这个参数(这里的arguments()不能理解,参数为什么能够执行)
3、调用obj的method方法,传入一个参数fn;
4、调用obj的method方法,这次传入2个参数fn 和123.

我感觉越看越懵

@RookieDay
Copy link
Author

@hellochenk
下面是我的理解,有什么问题还望指正^_^

  • 对于this的理解,常说的一句话是-- 谁调用它this就代表谁
  • 对于method里面fn的理解, fn是传参传出来的,这里fn的执行属于函数调用模式,this就代表是全局对象window
  • arguments[0]() 的理解
arguments这个伪数组对象存的传入的参数, arguments 也就是可以理解为 [fn,123,345..,...,] ,传入的参数
组成数组,arguments[0]() 属于方法调用模式,this代表调用者,所以this 代表arguments ,执行arguments[0]() 
也就是arguments.fn(), this.length 代表arguments参数的个数

可以尝试打印出arguments看一下

var length=10;
function fn(){
    console.log(this.length);
}
var obj = {
    length:5,
    method: function (fn) {

        fn(); 
        arguments[0](); 
		console.log('show: ' + arguments[0] + arguments[1])
    }
};
obj.method(fn);   此处arguments里面存的是fn
obj.method(fn, 123);此处arguments里面存的是fn和123

执行

obj.method(fn);  
obj对象调用method,执行fn()属于 函数调用模式,
this代表window, this.length --> window.length --> 全局里面的length值-->10
执行arguments[0](); 属于方法调用模式,this代表调用者,所以this代表arguments,
this.length 代表 arguments参数个数--->1
obj.method(fn, 123); 
obj对象调用method,执行fn()属于 函数调用模式,
this代表window, this.length --> window.length --> 全局里面的length值-->10
执行arguments[0](); 属于方法调用模式,this代表调用者,所以this代表arguments,
this.length 代表 arguments参数个数--->2

@hellochenk
Copy link

@RookieDay

赞美大神,开头的谁调用它this就代表谁一句话就简单解释了this,最后的解释也非常详细。
我只关注了obj里面method中的fn()和arguments()执行后会发生什么事情,
却没理解这几行代码究竟是想表达什么(this的指向),真是受益匪浅。

@zhishaofei3
Copy link

zhishaofei3 commented Jun 19, 2017

arguments0; 的时候 this指向arguments,所以arguments.length是1 也就是fn函数

var length=10;
function fn(){
    console.log(this.length);
    debugger;//可以通过debugger断点调试,观察this的值
}
var obj = {
    length:5,
    method: function (fn) {

        fn(); 
        arguments[0](); 
    }
};
obj.method(fn);
obj.method(fn, 123);

@SoftwareEngineerPalace
Copy link

为什么要思考这种没意义的问题 把功能实现不就行了

@longing81
Copy link

一般来说,this有四种绑定规则。1.函数调用模式:this指向全局;2.方法调用模式:this指向方法所在对象;3.call/apply/bind的显示绑定;4.new自动绑定到新建对象。

我想在这道题里可以把第二个理解为方法调用模式,arguments数组也是对象arguments[0]为fn即arguments对象有一个方法fn,此时this.length即为arguments.length

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants