用最简洁的语言,准确的描述复杂的概念,提炼才是学习的本质!
Contents
this 指向的对象
函数定义
function
中this
指向,总是指向function
的调用者
1 2 3 4 5 6 7 8 9 10 11 12 |
function func() { this.name = 'kk' } func() console.log(window.name) //kk console.log(window.func === func) //true let person = {} person.setName = func person.setName() console.log(person.name) //kk |
this
可以被call
,apply
,bind
函数来修改this的指向-
匿名函数
this
默认指向window
, 可以被修改 -
bind
只生效一次,且无法被apply
,call
再次覆盖
1 2 3 4 5 6 7 8 9 |
function f(){ return this.a; } var g = f.bind({a:"azerty"}); // bind只生效一次! console.log(g()); // azerty console.log(g.bind({a:'yoo'})()) // azerty console.log(g.apply({a:'yoo'})) // azerty console.log(g.call({a:'yoo'})) // azerty |
箭头函数(ES6扩展)
-
箭头函数不会创建自己的
this
指向 -
箭头函数中
this
永远指向当前运行时
的上下文,且不能被修改
1 2 3 4 5 6 7 8 9 10 |
let m = {name: 'Jack'} let person = { who: () => { var w = () => {return this} return w() } } console.log('2',person.who2()) //this -> window console.log('2',person.who2.bind(m)()) //this -> window |
Function vs 箭头函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
let m = {name: 'Jack'} let person = { who: function() { var w = () => {return this} return w() }, who2: () => { var w2 = () => {return this} return w2() } } console.log('1',person.who()) //this -> person console.log('1',person.who.bind(m)()) //this -> m console.log('2',person.who2()) //this -> window console.log('2',person.who2.bind(m)()) //this -> window |
变量作用域
javascript 没有块级作用域
js
使用的是函数级作用域
js
没有块级作用域,就意味着一进入函数,变量就要马上被创建出来,这就是所谓的变量提升(hoisting)
示例1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var b = 'hello'; (function() { console.log(b) [code block] })() 当 [code block] 为空时 console.log(b) //hello 当 [code block] 为var b = 'world'时 console.log(b) //undefined 当 [code block] 为let b = 'world'时 console.log(b) //Uncaught ReferenceError: b is not defined |
示例2
1 2 3 4 5 6 7 8 9 10 11 12 |
(function func() { var x = 1; console.log(x); // 1 if (true) { var x = 2; console.log(x); //2 } console.log(x); // 2 })() // 输出结果为:1,2,2 意味着if{}代码块内部的x变量,作用域是整个函数,所以将第一个声明的x变量覆盖了 |
Let 变量定义 (ES6扩展)
let
定义变量在Global上下文中,不会被附加到window属性上
1 2 3 4 5 |
let me = 'go'; // globally scoped var i = 'able'; // globally scoped console.log(window.me); // undefined console.log(window.i); // 'able' |
let
定义的变量是块级作用域
,不会产生变量提升
的问题
1 2 3 4 5 6 7 8 9 10 11 12 |
(function func() { let x = 1; console.log(x); // 1 if (true) { let x = 2; console.log(x); //2 } console.log(x); // 2 })() // 输出结果为:1,2,1 ,明显看到let声明的x变量,作用域并没有覆盖到if{}外部的x变量作用域 |
- babel 在转换let到es5代码时,是通过修改变量名来实现的
1 2 3 4 5 6 7 8 9 10 11 12 |
//babel 转义后的 ES5 代码 (function func() { var x = 1; console.log(x); // 1 if (true) { var _x = 2; console.log(_x); //2 } console.log(x); // 2 })(); |