javascript高级语法之一 : this的指向(箭头函数)
javascript高级语法之一 : this的指向(箭头函数)
启示 :
1.函数在调用时,javascript会默认给this绑定一个值;
2.this的绑定和定义的位置(编写的位置)没有关系;
3.this的绑定和调用方式以及调用的位置有关系
4.this时运行时被绑定的
绑定规则 :
优先级 :
默认绑定最低
显式绑定 > 隐式绑定
new绑定 > 隐式绑定
new > bind [ new不可以和apply/call 一起使用, 但是bind可以和new一起使用 ]
bind > apply/call
总结 : new > bind > apply/call > 隐式 > 默认
绑定一 : 默认绑定
普通函数被独立调用指向window 【 严格模式下,独立调用的函数指向undefined 】
绑定二 : 隐式绑定
如果函数它是被某一个对象来引用并且调用它, 那么this会指向这个对象(调用的那个调用)
绑定三 : 显示绑定 [ call - apply - bind(很少使用)]
call 和 apply 方法 :
1.第一个参数是相同的,要求传入一个对象
这个对象就是给this准备的,在调用这个函数时,会给this绑定到这个传入的对象上
2.后面的参数 : call为参数列表 , apply 为数组
bind 方法 : 会生成一个新的绑定函数,不用每次都call或者apply
1.第一个参数也是要传入一个对象
2.后面的参数 : 参数列表
绑定四 : new绑定
1.创建新对象
2.将this指向这个空对象
3.执行函数体中的代码
4.没有显示返回非空对象时,默认返回这个对象
内置函数的this
定时器 ==> window
foreach ==> 默认window , 第三个参数可以改变this的指向
点击事件 ===> 元素本身
特殊的[规则之外] :
1.如果在显示绑定中,我们传入一个null 或者 undefined , 那么这个显示绑定会被忽略 , 使用默认规则(window)
2.间接函数引用
绑定一 : 默认绑定 - 代码
// 定义函数 // 1.普通的函数被独立的调用 function foo() { console.log("foo:", this) } foo() //window // 2.函数定义在对象中, 但是独立调用 var obj = { name: "why", bar: function() { console.log("bar:", this) } } var baz = obj.bar baz() //windows // 3.高阶函数 function test(fn) { fn() } test(obj.bar) //window // 4.严格模式下, 独立调用的函数中的this指向的是undefined // "use strict"
绑定二 :隐式绑定 - 代码
// 隐式绑定 function foo() { console.log("foo函数:", this) } var obj = { bar: foo } obj.bar() // obj
绑定四 : new绑定 - 代码
function foo() { this.name = "why" console.log("foo函数:", this) } new foo() // foo
绑定三 : 显示绑定[ apply - call ] - 代码
// call/apply function foo(name, age, height) { console.log("foo函数被调用:", this) console.log("打印参数:", name, age, height) } // 普通()调用 foo("why", 18, 1.88) // apply // 第一个参数: 绑定this // 第二个参数: 传入额外的实参, 以数组的形式 foo.apply("apply", ["kobe", 30, 1.98]) // call // 第一个参数: 绑定this // 参数列表: 后续的参数以多参数的形式传递, 会作为实参 foo.call("call", "james", 25, 2.05)
绑定三 : 显示绑定[ bind ] - 代码
function foo(name, age, height, address) { console.log("foo:", this) console.log("参数:", name, age, height, address) } var obj = { name: "why" } // 需求: 调用foo时, 总是绑定到obj对象身上(不希望obj对象身上有函数) // 1.bind函数的基本使用 // var bar = foo.bind(obj) // bar() // this -> obj // 2.bind函数的其他参数(了解) var bar = foo.bind(obj, "kobe", 18, 1.88) bar("james") //obj
内置函数 的 this :
<body> <button>按钮</button> <script> // 内置函数(第三方库): 根据一些经验 // 1.定时器 - window setTimeout(function() { console.log("定时器函数:", this) }, 1000) // 2.按钮的点击监听 var btnEl = document.querySelector("button") btnEl.onclick = function() { console.log("btn的点击:", this) //元素本身 } btnEl.addEventListener("click", function() { console.log("btn的点击:", this) //元素本身 }) // // 3.forEach var names = ["abc", "cba", "nba"] names.forEach(function(item) { console.log("forEach:", this) //window }, "aaaa") //第三个参数就是改变this 的 </script> </body>
优先级 : - 代码
<script> function foo() { console.log("foo:", this) } // 比较优先级: // 1.显式绑定绑定的优先级高于隐式绑定 // 1.1.测试一:apply高于默认绑定 var obj = { foo: foo } obj.foo.apply("abc") obj.foo.call("abc") // 1.2.测试二:bind高于默认绑定 var bar = foo.bind("aaa") var obj = { name: "why", baz: bar } obj.baz() // 2.new绑定优先级高于隐式绑定 var obj = { name: "why", foo: function() { console.log("foo:", this) console.log("foo:", this === obj) } } new obj.foo() // 3.new/显式 // 3.1. new不可以和apply/call一起使用 // 3.2. new优先级高于bind function foo() { console.log("foo:", this) } var bindFn = foo.bind("aaa") new bindFn() // 4.bind/apply优先级 // bind优先级高于apply/call function foo() { console.log("foo:", this) } var bindFn = foo.bind("aaa") bindFn.call("bbb") </script>
箭头函数
1.箭头函数不会绑定this[写了this的话,会跟上层的this一致,因为他是在找变量this所以找到了上一层的this] , 没有arguments属性
2.箭头函数不能作为构造函数来使用 ( 不能和new一起来使用 , 会抛出错误 [ 因为es6后不会使用new,用class来代替了 ])
3.箭头函数的简写 :
箭头函数只有一个参数,那么( ) 可以省略
箭头函数的函数体只有一行代码,那么 { } 可以省略 , 并且 这行代码 的结果 会作为这个函数的返回值 默认返回
默认返回值是一个对象,那么这个对象必须加( ) [ 这个在react中会经常使用 redux ]
本文来自博客园,作者:杨建鑫,转载请注明原文链接:https://www.cnblogs.com/qd-lbxx/p/16490649.html