博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Brief introduction of how to 'Call, Apply and Bind'
阅读量:6421 次
发布时间:2019-06-23

本文共 3435 字,大约阅读时间需要 11 分钟。

关于 this

在绝大多数情况下,函数的调用方式决定了this的值。this不能在执行期间被赋值,并且在每次函数被调用时this的值也可能会不同。

全局 this

window.something = 'I love JavaScript'console.log(this.something) // 'I love JavaScript'console.log(window === this) // true

调用全局 function

var a = 1function test() { console.log(this.a) }test() // 1 - still remains the window reference

调用对象中的 function

this.a = 'I am in the global scope'function Test() {  this.a = 'I am in the test scope'  this.show = function() { console.log(this.a) }}Test.prototype.display = function () { console.log(this.a) }var test = new Test() // updated the scope of thistest.show() // I am in the test scopetest.display() // I am in the test scope

关于 call / apply

JavaScript 内部提供了一种机制,让我们可以自行手动设置 this 的指向。它们就是 call 与 apply。所有的函数都具有着两个方法。它们除了参数略有不同,其功能完全一样。它们的第一个参数都为 this 将要指向的对象。

一个最简单的继承

function Laptop(name, storage) {  this.name = name  this.storage = storage}function Dell(name, storage, company) {  Laptop.call(this, 'Dell', 1024)  this.company = company}console.log(new Dell('Dell', 1024, 'Dell Inc').storage)

改变 this

var obj = {  entry: 'mammals-banana-tower',  duration: 0}function breed(name) {  console.log('Show this breeding info', name, this.entry, this.duration)  console.log(this === obj)}breed() // this => windowbreed.call(obj, 'Frank') // this => obj

注:当没有传递任何参数作为 call() 的第一个参数时,在非严格模式下,this 会指向 window。

实现一个简单的 call

var _call = function (that) {  that = that ? Object(that) : window  that.func = this  function formatArgs(oArgs, sign) {    var _args    for (var i = 1, len = oArgs.length; i < len; i++) {      _args.push(sign ? ('_param_' + i) : oArgs[i])    }    return _args  }  var args = formatArgs(arguments)  var newFunc = (new Function('args', 'return that.func(' + formatArgs(args, true).toString() + ')'))(args)  that.func = null  return newFunc}

关于 bind

() => {} 和 bind this

用过 React 的同学都知道,当使用 class component 时,需要在 constructor 绑定当前的成员函数,或者针对事件委托的情况下,也需要进行绑定;ES6 箭头函数可以让我们更专注于具体的实现逻辑,简化了 this 操作

// ES5// // constructor() { this.handleClick = this.handleClick.bind(this) }// ES6//  handleClick()}>// handleClick = () => {}

无效的 re-bound

var f = function() { console.log(this.text) }f = f.bind({ text: 'I was bound' }).bind({ text: 'I won't be bound' })f() // I was bound

很容易发现,f.bind() 返回的绑定函数对象仅在创建是保留当前的上下文(或者传入的参数),因此无法在第二次进行重绑定。

一个相对完善的 bind

var _bind = function (that) {  var fBound,    target = this,    slice = Array.prototype.slice,    toStr = Object.prototype.toString,    args = slice.call(arguments, 1); // except that  if (typeof target !== 'function' || toStr.call(target) !== '[object Function]') {    throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');  }  var binder = function () {    var oArgs = args.concat(slice.call(arguments))    if (this instanceof fBound) {      var result = target.apply(this, oArgs);      return Object(result) === result ? result : this;    } else {      return target.apply(that, oArgs);    }  };  var i = 0,    params = [],    paramLength = Math.max(0, target.length - args.length);  for (; i < paramLength; i++) {    params.push('_param_' + i);  }  fBound = (new Function(    'binder',    'return function(' + params.join(',') + ') { return binder.apply(this,arguments); }'  ))(binder);  // maintain the reference of prototype  if (target.prototype) {    var fNOP = function () { };    fNOP.prototype = target.prototype;    fBound.prototype = new fNOP();    fNOP.prototype = null;  }  return fBound;};

参考

转载地址:http://salra.baihongyu.com/

你可能感兴趣的文章
jquery checkbox选中
查看>>
ThreadPoolExecutor使用介绍
查看>>
Multicast on Openstack
查看>>
iOS开发之地图与定位
查看>>
数论 - 简单数位推理 --- NYIST 514
查看>>
eclipse代码自动提示设置、如何配置eclipse的代码自动提示功能(同时解决自动补全变量名的问题)?...
查看>>
浅谈管道模型(Pipeline)
查看>>
poj 2773(容斥原理)
查看>>
HTML5 标准规范完成了
查看>>
机器字长 32位与64位的区别
查看>>
(原创)大数据时代:基于微软案例数据库数据挖掘知识点总结(Microsoft 神经网络分析算法)...
查看>>
第三章(附)mysql表类型MyISAM和InnoDB区别(决定了是否支持事务)
查看>>
hdu 1316 How Many Fibs? (模拟高精度)
查看>>
Ubuntu server下搭建Maven私服Nexus
查看>>
Android网络图片显示在ImageView 上面
查看>>
如何对sharepoint图片库的文件夹的图片按照时间排序并分页显示
查看>>
Controllerizing the ScrollViewer Thumbnail
查看>>
游标的使用
查看>>
Transform数据权限浅析2之利用Java完成权限设置
查看>>
android JAVA字符串转日期或日期转字符串(转)
查看>>