ES5

101 阅读4分钟

ES5

严格模式

  • ES5引入了严格模式,浏览器会对JS的要求更加苛刻,语法格式要求更细致,更符合逻辑

严格模式的优点

  • 消除了一些不合理的地方
  • 提高了代码的运行效率
  • 让代码运行时更安全

严格模式的注意点

  • 不能省略var等关键字
  • 禁止函数使用this关键字指向window(全局变量)
  • 禁止八进制方法
  • 不允许在非函数的代码块内声明函数
  • 在严格模式下,,arguments变量,形参不会改变(不会同步)
  • 作用域 跟 块级作用域会受限制
// -----eval函数作用
"use strict";
var a= 10;
eval("var a =20;console.log('内',a)");
console.log("外",a);

严格模式的分类

全局严格模式

  • 函数外部的,全局的"use strict";
  • 必须放在第一行,且它的前面不能有别的代码
"use strict";
function fn(){
    console.log(this); //加上全局严格模式:undefined,没加this是window
}
fn();

局部严格模式

  • 函数内部的,局部的"use strict";
  • 必须放在函数内部的第一行,且它的前面不能有别的代码存在
function fn1(){
    //局部严格模式
    "use strict";
    console.log(this);//加了严格之后,undefined,没有加指向window
}

fn1()

this关键字

this的指向

  • 每一个函数内部都有一个关键字是 this

  • 可以让我们直接使用的

  • 重点: 函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有关系

  • 函数内部的 this 指向谁,取决于函数的调用方式

全局定义的函数直接调用,this => window

function fn() {
  console.log(this)
}
fn()
// 此时 this 指向 window

对象内部的方法调用,this => 调用者

var obj = {
  fn: function () {
    console.log(this)
  }
}
obj.fn()
// 此时 this 指向 obj

定时器的处理函数,this => window

setTimeout(function () {
  console.log(this)
}, 0)
// 此时定时器处理函数里面的 this 指向 window

事件处理函数,this => 事件源

div.onclick = function () {
  console.log(this)
}
// 当你点击 div 的时候,this 指向 div

自调用函数,this => window

(function () {
  console.log(this)
})()
// 此时 this 指向 window

改变thi指向的三个方法

  • 刚才我们说过的都是函数的基本调用方式里面的 this 指向
  • 我们还有三个可以忽略函数本身的 this 指向转而指向别的地方
  • 这三个方法就是 call / apply / bind
  • 是强行改变 this 指向的方法

call

  • call 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向

  • 语法: 函数名.call(要改变的 this 指向,要给函数传递的参数1,要给函数传递的参数2, ...)

var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
fn.call(obj, 1, 2)
  • fn() 的时候,函数内部的 this 指向 window
  • fn的this指向变成了obj
  • fn.call(obj, 1, 2) 的时候,函数内部的 this 就指向了 obj 这个对象
  • 使用 call 方法的时候
    • 会立即执行函数
    • 第一个参数是你要改变的函数内部的 this 指向
    • 第二个参数开始,依次是向函数传递参数

apply

  • apply 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向

  • 语法: 函数名.apply(要改变的 this 指向,[要给函数传递的参数1, 要给函数传递的参数2, ...])

var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
fn.call(obj, [1, 2])
  • fn() 的时候,函数内部的 this 指向 window
  • fn原来的this指向变成了obj
  • fn.apply(obj, [1, 2]) 的时候,函数内部的 this 就指向了 obj 这个对象
  • 使用 apply 方法的时候
    • 会立即执行函数
    • 第一个参数是你要改变的函数内部的 this 指向
    • 第二个参数是一个 数组,数组里面的每一项依次是向函数传递的参数

bind

  • bind 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向

  • 和 call / apply 有一些不一样,就是不会立即执行函数,而是返回一个已经改变了 this 指向的函数

  • 语法: var newFn = 函数名.bind(要改变的 this 指向); newFn(传递参数)

var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
var newFn = fn.bind(obj)
newFn(1, 2)
  • bind 调用的时候,不会执行 fn 这个函数,而是返回一个新的函数
  • 这个新的函数就是一个改变了 this 指向以后的 fn 函数
  • fn(1, 2) 的时候 this 指向 window
  • newFn(1, 2) 的时候执行的是一个和 fn 一摸一样的函数,只不过里面的 this 指向改成了 obj

call apply bind的区别

bind apply call 的区别

  • 他们都可以改变函数的this指向
  • bind不会立即执行,需要手动设置
  • apply和call都会立即执行,区别在与apply的第二个参数是一个数组,call从第二个参数起可以设置很多个参数