一、概述
我们常见的window属性和方法有alter,document,parseInt,setTimeout,setInterval,localtion等等,这些在默认的情况下是省略了window前缀的。(window.alter = alter)。
1. strict mode
strict mode:js的严格模式,用于指定代码在严格条件下执行。
为什么使用严格模式?
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
同样的代码,在"严格模式"中,可能会有不一样的运行结果;
特点:
严格模式下,没有直接的挂载者的话,this默认为undefined,正常模式下,没有直接的挂载者(或称调用者)的函数中this是指向window,这是约定俗成的;
arguments,不允许对arguments赋值,禁止使用arguments.callee,arguments不再追踪参数的变化;
不用var声明不会提升成全局变量,而是报错;
2. this调用的四种模式
首先牢记:js function有四种方式调用,每一种的this都不同。
2.1 方法调用
如果函数是一个对象的方法,则它的this指针指向这个对象。
var x = 11; let obj = { x: 22, say: function () { console.log(this.x) //this绑定到了obj对象上 } }
obj.say(); //console.log输出的是22
2.2 函数调用
所谓函数调用,指的是声明一个function,然后调用。正常模式this指向window,严格模式是undefined。
var a = 11 function test1() { this.a = 22; // 因为是函数调用,所以这里的this指向了window let b = function () { console.log(this.a); //这里也指向了window }
b() // 这里也为函数调用 } let b = test1()
function test1() {
'use strict'
console.log(this)
}
test1() // 开启严格模式,this指向undefined
2.3 构造函数调用
如果是该函数是一个构造函数,this指向new出来的新对象。
var a = 11 //相当于window.a = 11, 函数中的this是根据上下文改变的 function test1() { console.log(this) // 指向新创建出来的这个对象,这和java一样 console.log(this.a) // undefined,这个对象还没有a属性 this.a = 22 console.log(this.a) // 22 this指向 new 出来的对象 let b = function () { console.log(this.a); // 11 this指向 window对象 } console.log(b) b() // 这里为函数调用,所以函数中的this指向window对象 } new test1()
2.4 apply & call & bind
这类就是改变this,后面再来补充......
2.5 传统的函数调用存在的问题?
js的设计存在一个错误。当一个对象的方法返回了一个函数,在调用这个函数时,函数调用中的this应该绑定到外部函数的this,
即应该绑定到函数b上,但是它却直接绑定到了window上。
虽然严格模式规定了this不指向window,但是并没有解决这个问题,于是箭头函数来了。
var a = 11 let obj = { a: 22, b: function () { console.log(this) // 对象的方法,所以,这里的this指向当前对象 return function () { console.log(this) // 方法调用,所以,这里的this指向window console.log(this.a) // 11 } } } obj.b()()
3. 箭头函数
箭头函数用 " => " 符号来定义。
箭头函数相当于匿名函数,所以采用函数表达式的写法。
在使用回调函数时,建议使用匿名函数,这肯定是没有问题的。
let:
用来声明变量,只在let
命令所在的代码块内有效;
const:
声明一个只读的常量,一旦声明,常量的值就不能改变;
箭头函数的使用实例:箭头函数的使用与java中的lambda类似
// 原始写法(没有使用箭头函数) let sum = function (x, y) { return x+y } console.log(sum(1, 2)) // 完整的写法,左边小括号,右边大括号(标准格式) const sum1 = (x, y) => {return x+y} console.log(sum1(1, 3)) // 当要执行的代码块只有一条return语句时,可省略大括号和return关键字 let sum2 = (x, y) => x+y console.log(sum2(1, 4)) // 当传入的参数只有一个时,可以省略左边的小括号 let sum3 = x => 1+5 console.log(sum3(5)) // 当不需要参数时,使用空的圆括号 let sum4 = () => 1+6 console.log(sum4()) // 箭头函数在回调函数中是很简洁的 const array = [1, 2, 3] let numbers = array.map(x => x*x); console.log(numbers) // [1, 4, 9] // 在排序中的使用 let sort = array.sort((x, y) => y - x) console.log(sort) // [3, 2, 1]
3.1 箭头函数中的this问题
箭头函数不会创建自己的this,它只会从自己的作用域链的上层继承this,它的this指向始终是看它的上一层函数作用域中的this,如果没有上一层函数,就是window。
(1) 箭头函数本身与say平级以key:value的形式存在, 箭头函数本身所在的对象为obj,而obj的父执行上下文就是window,因此这里的this.x实际上表示的是window.x,因此输出的是11。
var x = 11 let obj1 = { x:22, say:()=>{ console.log(this) // 指向window console.log(this.x); } } obj1.say(); // 11
参考文档: