this指向,call(), apply(), bind(),严格模式

函数的定义

var fn = new Funtion('x', 'y', 'console.log(x + y)');
// 所有的函数都是 Funtion 的实例对象
console.log(fn instanceof Object); // true 函数属于对象

函数内 this 的指向

这些 this 的指向,是当我们调用的时候确定的,调用的方式不同决定了this指向的不同;一般情况下指向我们的调用者

调用方式 this指向
普通函数 window
构造函数 实例对象,原型对象里面的方法也指向实例对象
对象方法调用 指向这个对象
事件绑定调用 绑定事件的这个对象
定时器函数 window
立即执行函数 window

改变函数内部 this 指向

JavaScript 专门提供了一些方法帮助我们优雅的处理函数内部 this 的指向问题;常用的有 bind() call() apply()

call();

call() 方法调用一个对象,简单理解为调用函数的方式,但是它可以改变函数内部this 的指向

主要用于模拟继承

fn.call(thisArg, arg1, arg2...);
var o = {name: 'zs'};
var fn = function () {console.log(this)}
fn.call(o); // 此时 this 就指向了 o

apply();

apply() 方法调用一个函数,简单理解为调用函数的方式,但是它可以改变函数内部this 的指向;

传递的值必须在数组里面

主要用于计算 Math.max.apply(Math, [22, 2, 3, 444]);

fn.apply(thisArg, [argArray]);
var fn = function (x, y){console.log(x + y)};
fn.apply(o, [1, 2]); // 此时 this 就指向了 o 并且求结果为 3

bind()

bind() 方法不会调用函数,但是能改变函数内部this 的指向

如果有的函数不需要立即调用,但是又想改变这个函数内部this的指向此时可以使用bind

var btns = document.querySelectorAll('button');
for (var i = 0; i < btns.length; i++) {
  btns[i].onclick = function () {
    this.disabled = true;
    setTimeout(function () {
      // 如果存在多个相同的btn此时就不能像一个btn那样在定时器内部修改disabled属性了
      this.disabled = false;
    }.bind(this), 2000);
  }
}
fn.bind(thisArg, arg1, arg2...); // 返回由指定的this值和初始化参数改造的**原函数拷贝**
var fn = function (x, y){console.log(x + y);}
var f = fn.bind(o, 1, 2); // 只是修改了this指向并没有调用,因为是拷贝了原函数所以可以赋值给一个变量
f(); // 通过f调用

严格模式 ES5

严格模式在IE10一声的版本才支持,旧版本中会被忽略

  1. 消除了 js 语法的一些不合理,不严谨之处;
  2. 提高了编译器效率,增加运行速度
  3. 禁用了一些未来版本可能出现的关键字

开启严格模式

严格模式分为两种,全局严格模式和函数严格模式

// 全局严格模式; 在script标签中或者单独的js中的第一行写入以下代码
'use strict';
// 函数严格模式;
(function () {
   'use strict';
})();
  • 变量规定
    • 严格模式下必须用var去声明变量
    • 严禁删除已经声明的变量 例如:delete x 是不被允许的
  • this 指向问题
    • 全局作用域中函数的this指向是undefined而不是window
    • 定时器,事件函数中this指向的函数window
    • 不允许在非函数代码块里面声明函数 比如 if for

猜你喜欢

转载自www.cnblogs.com/article-record/p/12682765.html
今日推荐