zoukankan      html  css  js  c++  java
  • 关于 JS this

    关于 JS this

    1. this 与 普通函数

    普通函数 this 永远指向它的调用对象

    var obj = {
        a:10,
        b:{
            a:20,
            fn:function(){
                console.log(this.a);
            }
        }
    }
    obj.b.fn(); //=> 20
    

    对象 b 调用 fn 函数 this.a 为 20。

    var obj2 = {
        a:10,
        b:{
            fn:function(){
                console.log(this.a);
            }
        }
    }
    obj2.b.fn(); //=> undefined
    

    对象 b 中无 a 字段, this.a 为 undefined。

    var obj3 = {
        a:10,
        b:{
            a:20,
            fn:function(){
                console.log(this);
                console.log(this.a);
            }
        }
    }
    var j = obj3.b.fn;
    j(); //=> window, undefined
    

    这里直接获取里fn对象,没有通过对象去调用。非严格模式下,this 默认指向全局对象window。

    var obj4 = {
        a:10,
        b:{
            a:20,
            fn:function(){
                "use strict";
                console.log(this);
                console.log(this.a);
            }
        }
    }
    var g = obj4.b.fn;
    g(); //=> undefined, TypeError: Cannot read property 'a' of undefined
    

    而严格模式下, this 为 undefined。

    2. this 与 bind、call、apply

    function.bind(thisArg[, arg1[, arg2[, ...]]]) 最简单的用法是创建一个函数,不论怎么调用,这个函数都有同样的 this 值。
    function.call(thisArg, arg1, arg2, ...)、function.apply(thisArg, [argsArray]) call、apply 的作用类似都是为调用函数指定this。

    function fn() {
        return this.user;
    }
    
    console.log(fn.call({ user: "li" })); //=> li
    
    console.log(fn.apply({ user: "wang" })); //=> wang
    
    var bfn = fn.bind({ user: "gao" });
    console.log(bfn()); //=> gao
    
    
    console.log(bfn.call({ user: "liu" })); //=> gao
    
    console.log(bfn.apply({ user: "liu" })); //=> gao
    
    console.log(bfn.bind({ user: "liu" })()); //=> gao
    
    var obj = { user: 'zhang', f: fn, g: bfn };
    console.log(obj.f(), obj.g()); //=>  zhang, gao
    

    对 bind 产生的函数使用,再使用 call、apply、bind, 指向的 this 仍然是初次bind的值。

    function list() {
        return Array.prototype.slice.call(arguments);
    }
    console.log(list(1, 2, 3)); //=> [1, 2, 3]
    
    function list2(){
        if(arguments){
            arguments.__proto__.slice = Array.prototype.slice;
            return arguments.slice();
        }
    }
    console.log(list2(4, 5, 6)); //=> [4, 5, 6]
    
    var leading37List = list.bind(null, 37);
    console.log(leading37List()); //=> [37]
    console.log(leading37List(1, 2, 3)); //=> [37, 1, 2, 3]
    

    在函数代码中,特殊对象 arguments 无需明确指出参数名,就能访问它们。arguments 自带 length 属性, Array.prototype.slice.call(arguments) 可以理解成 arguments.slice()

    3. this 与 箭头函数

    由于箭头函数不绑定this,它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值。

    var obj = {
        a: 10,
        b: function () {
            console.log(this.a, this)
        },
        c: () => console.log(this.a, this),
    }
    obj.b(); //=> 10, Object{...}
    obj.c(); //=> undefined, window{...} 
    
    obj.c.apply({ a: 'apply' }); //=> undefined, window{...} 
    obj.c.call({ a: 'call' }); //=> undefined, window{...} 
    obj.c.bind({ a: 'bind' })(); //=> undefined, window{...} 
    

    call() 、 apply() 、 bind() 方法对于箭头函数来说只是传入参数,对它的 this 毫无影响。

    function fn() {
        this.a = 20;
        this.b = () => console.log(this.a, this);
    }
    console.log((new fn()).b()) //=> 20, fn {a: 20, b: ƒ}
    

    箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。

    var lam = (...r) => { 
        console.log(r); 
    }
    lam(1,2,3); //=> Array : [1, 2, 3]
    

    箭头函数没有arguments,取而代之用rest参数…解决。

    var B = ()=>{
      value:1;
    }
    var b = new B(); //=> TypeError: B is not a constructor
    

    箭头函数作为匿名函数,没有构造函数,不能使用new。

    4. this 与 return

    如果返回值是 引用类型 对象,那么this指向的就是那个返回的对象;
    如果返回值是 非引用类型 对象那么this还是指向函数的实例。

    4.1 返回引用对象

    function fn()  
    {  
        this.user = '123';  
        return {};  
    }
    var a = new fn;  
    console.log(a.user); //=> undefined
    

    4.2 返回function对象

    function fn()  
    {  
        this.user = '123';  
        return function(){};
    }
    var a = new fn;  
    console.log(a.user); //=> undefined
    

    4.3 返回数字,值对象

    function fn()  
    {  
        this.user = '123';  
        return 123;
    }
    var a = new fn;  
    console.log(a.user); //=> 123
    

    4.4 返回undefined

    function fn()  
    {  
        this.user = '123';  
        return undefined;
    }
    var a = new fn;  
    console.log(a.user); //=> 123
    

    4.5 返回null

    function fn()  
    {  
        this.user = '123';  
        return null;
    }
    var a = new fn;  
    console.log(a.user); //=> 123
    

    返回目录

  • 相关阅读:
    'telnet' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
    Linux学习_009_VMware12.0 Pro 中安装 CentOS 6.8_超详解 + 高清大图
    Linux学习_008_Linux下的JDK和OpenJDK有什么具体的区别
    实战CentOS系统部署Hadoop集群服务
    开源多线程性能测试工具-sysbench
    Hadoop集群中Hbase的介绍、安装、使用
    Docker基础技术:Linux Namespace(上)
    带你走进rsync的世界
    5分钟教你Windows 10中将“运行”固定到开始菜单
    使用 Github Pages 发布你的项目文档
  • 原文地址:https://www.cnblogs.com/gaobw/p/11807098.html
Copyright © 2011-2022 走看看