禁止转载,必威:上面你知道'

至于 bind 你或者须要掌握的知识点以至选用境况

2016/08/18 · JavaScript · bind

正文小编: 伯乐在线 - 韩子迟 。未经作者许可,制止转发!
迎接参预伯乐在线 专栏撰稿人。

不看不理解,风流浪漫看吓意气风发跳,已经整整三个月未有更新 underscore 源码解读体系小说了。前边大家已经达成了 Object ,Array,Collection 上的恢弘方法的源码解析,本文开始来解读 Function 上的恢宏方法。

总体的 underscore 源码解读种类小说请移步 ,感觉还阔以的话,给个 star 激励下楼主呗 ^_^

那篇小说主要介绍了Javascript Function.prototype.bind详细分析的有关资料,需求的敌人可以参谋下

JavaScript 深切之bind的效仿完毕

2017/05/26 · JavaScript · bind

原稿出处: 冴羽   

javascript中bind函数的效果实例介绍,javascriptbind

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
button {background-color:#0f0;}
</style>
</head>
<body>
<button id="button"> 按钮 </button>
<input type="text">
<script>
var button = document.getElementById("button");
button.onclick = function() {
alert(this.id); // 弹出button
};
//可以看出上下文的this 为button
</script>
</body>
</html>

那会儿出席bind

复制代码 代码如下:

 var text = document.getElementById("text");
 var button = document.getElementById("button");
 button.onclick = function() {
 alert(this.id); // 弹出button
 }.bind(text);
 //能够看见上下文的this 为button

这会儿会意识this退换为text

函数字面量里也适用,指标是维持内外指向(this)不改变。

var obj = {
color: "#ccc", 
element: document.getElementById('text'),
events: function() {
document.getElementById("button").addEventListener("click", function(e) {
console.log(this);
this.element.style.color = this.color;
}.bind(this))
return this;
},
init: function() {
this.events();
}
};
obj.init();

那会儿点击开关text里的字会变色。可以预知this不为button而是obj。

bind()的主目的在于ie,6,7,8中不适用,供给扩张通过增加Function prototype能够兑现此办法。

if (!Function.prototype.bind) {

Function.prototype.bind = function(obj) {
var slice = [].slice, args = slice.call(arguments, 1), self = this, nop = function() {
}, bound = function() {
return self.apply(this instanceof nop ? this : (obj || {}),
args.concat(slice.call(arguments)));
};

nop.prototype = self.prototype;

bound.prototype = new nop();

return bound;
};
}

此时能够观察ie6,7,第88中学也支撑bind()。

复制代码 代码如下:

slice = Array.prototype.slice,

array = Array.prototype.slice.call( array, 0 );

将类似数组转变为数组

 

bind 简介

Ok,后日要讲的难为 bind。关于 bind,能够先活动楼主早前写的稿子 ECMAScript 5(ES5) 中 bind 方法简要介绍备忘,有个着力的定义。

bind() 方法会成立一个新函数,当以此新函数被调用时,它的 this 值是传递给 bind() 的率先个参数, 它的参数是 bind() 的任何参数和其原本的参数。

语法是这样样子的:

fun.bind(thisArg[, arg1[, arg2[, ...]]])

1
fun.bind(thisArg[, arg1[, arg2[, ...]]])
  • thisArg 当绑定函数被调用时,该参数会作为原函数运营时的 this 指向。当使用 new 操作符调用绑定函数时,该参数无效。
  • arg1, arg2, … (可选)当绑定函数被调用时,这个参数加上绑定函数本人的参数会规行矩步顺序作为原函数运维时的参数。

  Function.prototype.bind分析

bind

一句话介绍 bind:

bind() 方法会创造贰个新函数。当那个新函数被调用时,bind() 的首先个参数将作为它运营时的 this,之后的风流倜傥种类参数将会在传递的实参前传出作为它的参数。(来自于 MDN )

经过大家得以率先得出 bind 函数的七个天性:

  1. 回到三个函数
  2. 能够流传参数

javascript bind的用法

javascript的bind

bind首假如为了转移函数内部的this指向,那个是在ECMA5随后参与的,所以IE8一下的浏览器不帮助

bind方法会创立七个新函数,称为绑定函数.当调用那些绑定函数时,绑定函数会以创办它时传入bind方法的率先个参数作为this,传入bind方法的第贰个以至后来的参数加上绑定函数运转时本身的参数依照顺序作为原函数的参数来调用原函数.

能够看这段实例:
var logger = { x: 0, updateCount: function(){ this.x++; console.log(this.x); }} // 上边两段代码的贯彻是同样的 document.querySelector('button').addEventListener('click', function(){ logger.updateCount();}); //用这种措施让代码更轻易,当然那只是bind的龙腾虎跃种现象document.querySelector('button').add伊芙ntListener('click', logger.updateCount.bind(logger));  

1.施用案例:

参数

bind 的第二个参数会作为原函数运转时的 this 指向,十分的少说;而第三个起来的参数是可选的,当绑定函数被调用时,这一个参数加上绑定函数自身的参数会坚守顺序作为原函数运转时的参数。怎么精通?

function fn(a, b, c) { return a + b + c; } var _fn = fn.bind(null, 10); var ans = _fn(20, 30); // 60

1
2
3
4
5
6
function fn(a, b, c) {
  return a + b + c;
}
 
var _fn = fn.bind(null, 10);
var ans = _fn(20, 30); // 60

fn 函数要求多少个参数,_fn 函数将 10 作为暗中认可的第二个参数,所以只供给传入八个参数就能够,假如您非常的大心传入了多个参数,放心,也只会取前多少个。

function fn(a, b, c) { return a + b + c; } var _fn = fn.bind(null, 10); var ans = _fn(20, 30, 40); // 60

1
2
3
4
5
6
function fn(a, b, c) {
  return a + b + c;
}
 
var _fn = fn.bind(null, 10);
var ans = _fn(20, 30, 40); // 60

那有甚用啊?要是某个函数,前几个参数已经 “钦定” 了,我们便得以用 bind 再次来到贰个新的函数。约等于说,bind() 能使贰个函数具备预设的启幕参数。那一个参数(借使部分话)作为 bind() 的第一个参数跟在 this 后边,之后它们会被插入到对象函数的参数列表的早先地方,传递给绑定函数的参数会跟在它们的后面。

function list() { return Array.prototype.slice.call(arguments); } var list1 = list(1, 2, 3); // [1, 2, 3] // Create a function with a preset leading argument var leadingThirtysevenList = list.bind(undefined, 37); var list2 = leadingThirtysevenList(); // [37] var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]

1
2
3
4
5
6
7
8
9
10
11
function list() {
  return Array.prototype.slice.call(arguments);
}
 
var list1 = list(1, 2, 3); // [1, 2, 3]
 
// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(undefined, 37);
 
var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]

bind()方法会创设八个新的函数,成为绑定函数。当调用这一个绑定函数时,绑定函数会以创制它时传出的率先个参数作为this,传入bind()方法的第叁个以至之后的参数加上绑定函数运转时自个儿的参数根据顺序作为原函数的参数来调取原函数。

归来函数的模拟完结

从第一个特色早先,大家比如:

var foo = { value: 1 }; function bar() { console.log(this.value); } // 重临了二个函数 var bindFoo = bar.bind(foo); bindFoo(); // 1

1
2
3
4
5
6
7
8
9
10
11
12
var foo = {
    value: 1
};
 
function bar() {
    console.log(this.value);
}
 
// 返回了一个函数
var bindFoo = bar.bind(foo);
 
bindFoo(); // 1

关于指定 this 的对准,大家能够利用 call 可能 apply 落到实处,关于 call 和 apply 的比葫芦画瓢达成,能够查看《JavaScript深刻之call和apply的模拟完毕》。大家来写第大器晚成版的代码:

// 第一版 Function.prototype.bind2 = function (context) { var self = this; return function () { self.apply(context); } }

1
2
3
4
5
6
7
8
// 第一版
Function.prototype.bind2 = function (context) {
    var self = this;
    return function () {
        self.apply(context);
    }
 
}

javascript:对于Functionprototypebind()那一个主意

Function.prototype.bind=function(thisArg){ var fn=this, slice=Array.prototype.slice, args=slice.call(arguments,1);//arguments1 var a1 = arguments; return function(){ alert(a1 == arguments);// 判定是还是不是为同叁个 return fn.apply(thisArg,args.concat(slice.call(arguments)));//arguments2 }};((function(){}).bind())(2);// 总是alert出false不是。第二个arguments是只thisArg,第二个则是指重临的百般函数的arguments。

Function.prototype.bind=function(thisArg){ var fn=this, slice=Array.prototype.slice, args=slice.call(arguments,1);//arguments1 alert(arguments[0]);// alert出1 return function(){ alert(arguments[0]);// alert出2 return fn.apply(thisArg,args.concat(slice.call(arguments)));//arguments2 }};((function(){}).bind(1))(2);  

!DOCTYPE htmlhtmlheadmeta charset="utf-8"stylebutton {background-color:#0f0;}/style/headbodybutton id="button" 按钮...

  

new

行使 bind 重临的结果依旧个 function,是个 function 就可以被 new 运算符调用,那么结果吧?标准中说的很驾驭了,当使用 new 操作符调用绑定函数时,bind 的第二个参数无效。

function Person(name, age) { this.name = name; this.age = age; } var _Person = Person.bind({}); var p = new _Person('hanzichi', 30); // Person {name: "hanzichi", age: 30}

1
2
3
4
5
6
7
function Person(name, age) {
  this.name = name;
  this.age = age;
}
 
var _Person = Person.bind({});
var p = new _Person('hanzichi', 30); // Person {name: "hanzichi", age: 30}

相似大家不会去那样用,可是只要要写个 bind 的 polyfill(),依然须求思索用 new 调用的动静。

大家也足以设置默许值(参谋上一小节),原先提供的那多少个参数依旧会被安放到构造函数调用的前头。

function Person(name, age) { this.name = name; this.age = age; } var _Person = Person.bind(null, 'hanzichi'); var p = new _Person(30); // Person {name: "hanzichi", age: 30}

1
2
3
4
5
6
7
function Person(name, age) {
  this.name = name;
  this.age = age;
}
 
var _Person = Person.bind(null, 'hanzichi');
var p = new _Person(30); // Person {name: "hanzichi", age: 30}

      实际运用中大家平日会蒙受那样的难点:

传参的效仿达成

接下去看第二点,能够流传参数。这么些就有一点令人费解了,小编在 bind 的时候,是还是不是能够传参呢?作者在试行 bind 重返的函数的时候,好还是倒霉传参呢?让大家看个例子:

var foo = { value: 1 }; function bar(name, age) { console.log(this.value); console.log(name); console.log(age); } var bindFoo = bar.bind(foo, 'daisy'); bindFoo('18'); // 1 // daisy // 18

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var foo = {
    value: 1
};
 
function bar(name, age) {
    console.log(this.value);
    console.log(name);
    console.log(age);
 
}
 
var bindFoo = bar.bind(foo, 'daisy');
bindFoo('18');
// 1
// daisy
// 18

函数须要传 name 和 age 四个参数,竟然还足以在 bind 的时候,只传一个name,在试行回来的函数的时候,再传另二个参数 age!

那可如何是好?不急,大家用 arguments 举办管理:

// 第二版 Function.prototype.bind2 = function (context) { var self = this; // 获取bind2函数从第一个参数到最终八个参数 var args = Array.prototype.slice.call(arguments, 1); return function () { // 这一年的arguments是指bind再次回到的函数字传送入的参数 var bindArgs = Array.prototype.slice.call(arguments); self.apply(context, args.concat(bindArgs)); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 第二版
Function.prototype.bind2 = function (context) {
 
    var self = this;
    // 获取bind2函数从第二个参数到最后一个参数
    var args = Array.prototype.slice.call(arguments, 1);
 
    return function () {
        // 这个时候的arguments是指bind返回的函数传入的参数
        var bindArgs = Array.prototype.slice.call(arguments);
        self.apply(context, args.concat(bindArgs));
    }
 
}

        var Mouse = function () {

配合 setTimeout

哪些时候便于错过 this 指向?恩,set提姆eout 是一个光景,相当的轻巧把 this 指向 window,当然,setInterval 也是同样。当使用对象的方法时,需求 this 援引对象,你恐怕需求显式地把 this 绑定到回调函数以便继续选择对象。

var canvas = { render: function() { this.update(); this.draw(); }, update: function() { // ... }, draw: function() { // ... } }; window.setInterval(canvas.render, 1000 / 60);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var canvas = {
  render: function() {
    this.update();
    this.draw();
  },
 
  update: function() {
    // ...
  },
 
  draw: function() {
    // ...
  }
};
 
window.setInterval(canvas.render, 1000 / 60);

用 canvas 写特效大概做游戏时常常会遇见类似的主题材料。下面的代码是失常的,render 方法中的 this 其实被针对了 window!大家得以用 bind,显式地把 this 绑定到回调函数以便继续使用该目的。

window.setInterval(canvas.render.bind(canvas), 1000);

1
window.setInterval(canvas.render.bind(canvas), 1000);

相近的事态还大概有 dom 的事件监听,一很大心大概 this 就被指向了 dom 成分。能够参照下从前做 bigrender 时写的那部分代码 。

var name = "pig";

构造函数效果的比葫芦画瓢达成

做到了这两点,最难的有的到啊!因为 bind 还也可以有多少个特色,就是

多少个绑定函数也能选拔new操作符成立对象:这种作为就像是把原函数当成构造器。提供的 this 值被忽略,同不时间调用时的参数被提须要模拟函数。

也正是说当 bind 重临的函数作为构造函数的时候,bind 时内定的 this 值会失效,但传播的参数依旧奏效。比如:

var value = 2; var foo = { value: 1 }; function bar(name, age) { this.habit = 'shopping'; console.log(this.value); console.log(name); console.log(age); } bar.prototype.friend = 'kevin'; var bindFoo = bar.bind(foo, 'daisy'); var obj = new bindFoo('18'); // undefined // daisy // 18 console.log(obj.habit); console.log(obj.friend); // shopping // kevin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var value = 2;
 
var foo = {
    value: 1
};
 
function bar(name, age) {
    this.habit = 'shopping';
    console.log(this.value);
    console.log(name);
    console.log(age);
}
 
bar.prototype.friend = 'kevin';
 
var bindFoo = bar.bind(foo, 'daisy');
 
var obj = new bindFoo('18');
// undefined
// daisy
// 18
console.log(obj.habit);
console.log(obj.friend);
// shopping
// kevin

在乎:就算在全局和 foo 中都宣示了 value 值,最终还是再次来到了 undefind,表达绑定的 this 失效了,假使我们探听 new 的效仿完毕,就能分晓这一年的 this 已经针对性了 obj。

(哈哈,笔者那是为自家的下活龙活现篇小说《JavaScript浓郁种类之new的模仿完结》打广告)。

就此大家得以因而改变再次来到的函数的原型来完结,让大家写一下:

// 第三版 Function.prototype.bind2 = function (context) { var self = this; var args = Array.prototype.slice.call(arguments, 1); var fbound = function () { var bindArgs = Array.prototype.slice.call(arguments); // 当做为构造函数时,this 指向实例,self 指向绑定函数,因为上边一句 `fbound.prototype = this.prototype;`,已经修改了 fbound.prototype 为 绑定函数的 prototype,此时结果为 true,当结果为 true 的时候,this 指向实例。 // 当做为普通函数时,this 指向 window,self 指向绑定函数,此时结果为 false,当结果为 false 的时候,this 指向绑定的 context。 self.apply(this instanceof self ? this : context, args.concat(bindArgs)); } // 修改重临函数的 prototype 为绑定函数的 prototype,实例就能够三回九转函数的原型中的值 fbound.prototype = this.prototype; return fbound; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 第三版
Function.prototype.bind2 = function (context) {
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);
 
    var fbound = function () {
 
        var bindArgs = Array.prototype.slice.call(arguments);
        // 当作为构造函数时,this 指向实例,self 指向绑定函数,因为下面一句 `fbound.prototype = this.prototype;`,已经修改了 fbound.prototype 为 绑定函数的 prototype,此时结果为 true,当结果为 true 的时候,this 指向实例。
        // 当作为普通函数时,this 指向 window,self 指向绑定函数,此时结果为 false,当结果为 false 的时候,this 指向绑定的 context。
        self.apply(this instanceof self ? this : context, args.concat(bindArgs));
    }
    // 修改返回函数的 prototype 为绑定函数的 prototype,实例就可以继承函数的原型中的值
    fbound.prototype = this.prototype;
    return fbound;
}

假诺对原型链稍有纠葛,能够查看《JavaScript深远之从原型到原型链》。

            // Look! no that = this!

tip

bind 仍可以做一些风趣的事务。

习以为常来讲,将贰个类数组转为数组,大家会用 slice(ie9- 不扶持)。参照他事他说加以考察

var slice = Array.prototype.slice; // slice.apply(arguments); // slice(arguments, 1);

1
2
3
4
var slice = Array.prototype.slice;
 
// slice.apply(arguments);
// slice(arguments, 1);

bind 能让调用变的愈发简明。

// same as "slice" in the previous example var unboundSlice = Array.prototype.slice; var slice = Function.prototype.call.bind(unboundSlice); // ... slice(arguments); // slice(arguments, 1);

1
2
3
4
5
6
7
8
// same as "slice" in the previous example
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);
 
// ...
 
slice(arguments);
// slice(arguments, 1);

再举个类似的例子,譬喻说大家要加上事件到多少个节点,for 循环当然未有别的难题,大家还足以 “剽窃” forEach 方法:

Array.prototype.forEach.call(document.querySelectorAll('input[type="button"]'), function(el){ el.addEventListener('click', fn); });

1
2
3
Array.prototype.forEach.call(document.querySelectorAll('input[type="button"]'), function(el){
  el.addEventListener('click', fn);
});

更上一层楼,我们得以用 bind 将函数封装的更好:

var unboundForEach = Array.prototype.forEach , forEach = Function.prototype.call.bind(unboundForEach); forEach(document.querySelectorAll('input[type="button"]'), function (el) { el.addEventListener('click', fn); });

1
2
3
4
5
6
var unboundForEach = Array.prototype.forEach
  , forEach = Function.prototype.call.bind(unboundForEach);
 
forEach(document.querySelectorAll('input[type="button"]'), function (el) {
  el.addEventListener('click', fn);
});

同等看似的,大家得以将 x.y(z) 形成 y(x,z) 的花样:

var obj = { num: 10, getCount: function() { return this.num; } }; var unboundBind = Function.prototype.bind , bind = Function.prototype.call.bind(unboundBind); var getCount = bind(obj.getCount, obj); console.log(getCount()); // 10

1
2
3
4
5
6
7
8
9
10
11
12
var obj = {
  num: 10,
  getCount: function() {
    return this.num;
  }
};
 
var unboundBind = Function.prototype.bind
  , bind = Function.prototype.call.bind(unboundBind);
 
var getCount = bind(obj.getCount, obj);
console.log(getCount());  // 10

再举个栗子。每间距豆蔻梢头秒在调节台打字与印刷 1-5,看起来是道考查闭包的精湛题目。

for(var i = 1; i <= 5; i++) { !function(i) { setTimeout(function() { console.log(i); }, i * 1000); }(i); }

1
2
3
4
5
6
7
for(var i = 1; i <= 5; i++) {
  !function(i) {
    setTimeout(function() {
      console.log(i);
    }, i * 1000);
  }(i);
}

ES6 下能用 let

for(let i = 1; i <= 5; i++) { setTimeout(function() { console.log(i); }, i * 1000); }

1
2
3
4
5
for(let i = 1; i <= 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, i * 1000);
}

也得以用 bind,瞬间逼格进步:

for(var i = 1; i <= 5; i++) { setTimeout(console.log.bind(console, i), i * 1000); }

1
2
3
for(var i = 1; i <= 5; i++) {
  setTimeout(console.log.bind(console, i), i * 1000);
}

function Person(name){

构造函数效果的优化完结

可是在那一个写法中,我们直接将 fbound.prototype = this.prototype,大家一向改造 fbound.prototype 的时候,也会一向更改函数的 prototype。那个时候,大家能够经过贰个空函数来扩充转载:

// 第四版 Function.prototype.bind2 = function (context) { var self = this; var args = Array.prototype.slice.call(arguments, 1); var fNOP = function () {}; var fbound = function () { var bindArgs = Array.prototype.slice.call(arguments); self.apply(this instanceof self ? this : context, args.concat(bindArgs)); } fNOP.prototype = this.prototype; fbound.prototype = new fNOP(); return fbound; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 第四版
Function.prototype.bind2 = function (context) {
 
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);
 
    var fNOP = function () {};
 
    var fbound = function () {
        var bindArgs = Array.prototype.slice.call(arguments);
        self.apply(this instanceof self ? this : context, args.concat(bindArgs));
    }
    fNOP.prototype = this.prototype;
    fbound.prototype = new fNOP();
    return fbound;
 
}

到此甘休,大的主题材料都曾经消除,给和谐三个赞!o( ̄▽ ̄)d

            this.position = [0, 0];

Read more

有关 bind 的牵线就到此地,下生机勃勃篇小说将组成 underscore 来说讲怎么着促成一个bind 的 polyfill。

  • Function.prototype.bind()
  • ECMAScript 5(ES5) 中 bind 方法简单介绍备忘
  • Javascript 中的 Bind ,Call 以及 Apply
  • Javascript 中 bind() 方法的运用与达成

打赏协助本人写出更加多好文章,多谢!

打赏作者

  this.name = name;

四个小标题

接下去管理些小难题:

1.apply 这段代码跟 MDN 上的稍有分裂

在 MDN 普通话版讲 bind 的模仿达成时,apply 这里的代码是:

self.apply(this instanceof self ? this : context || this, args.concat(bindArgs))

1
self.apply(this instanceof self ? this : context || this, args.concat(bindArgs))

多了一个有关 context 是还是不是留存的推断,不过这几个是谬误的!

比如:

var value = 2; var foo = { value: 1, bar: bar.bind(null) }; function bar() { console.log(this.value); } foo.bar() // 2

1
2
3
4
5
6
7
8
9
10
11
var value = 2;
var foo = {
    value: 1,
    bar: bar.bind(null)
};
 
function bar() {
    console.log(this.value);
}
 
foo.bar() // 2

以上代码常常情况下会打字与印刷 2,倘使换到了 context || this,这段代码就能够打印1!

故而这里不应有进行 context 的决断,大家查看 MDN 同样内容的土耳其共和国(Türkiye Cumhuriyeti)语版,就荒诞不经此个推断!

2.调用 bind 的不是函数如何是好?

分外,大家要报错!

if (typeof this !== "function") { throw new Error("Function.prototype.bind - what is trying to be bound is not callable"); }

1
2
3
if (typeof this !== "function") {
  throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}

3.自己要在线上用

那别忘了做个门道非凡:

Function.prototype.bind = Function.prototype.bind || function () { …… };

1
2
3
Function.prototype.bind = Function.prototype.bind || function () {
    ……
};

理所必然最佳是用es5-shim啦。

            if (document.addEventListener) {

打赏协助自身写出越来越多好小说,多谢!

必威 1

1 赞 7 收藏 评论

  this.getName = function(){

末段代码

由此最末尾的代码便是:

Function.prototype.bind2 = function (context) { if (typeof this !== "function") { throw new Error("Function.prototype.bind - what is trying to be bound is not callable"); } var self = this; var args = Array.prototype.slice.call(arguments, 1); var fNOP = function () {}; var fbound = function () { self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments))); } fNOP.prototype = this.prototype; fbound.prototype = new fNOP(); return fbound; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Function.prototype.bind2 = function (context) {
 
    if (typeof this !== "function") {
      throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
    }
 
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);
    var fNOP = function () {};
 
    var fbound = function () {
        self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
    }
 
    fNOP.prototype = this.prototype;
    fbound.prototype = new fNOP();
 
    return fbound;
 
}

                document.addEventListener('mousemove', ?);   //this.move?  

关于作者:韩子迟

必威 2

a JavaScript beginner 个人主页 · 小编的小说 · 9 ·    

必威 3

    setTimeout(function(){

深远体系

JavaScript浓厚体系目录地址:。

JavaScript浓烈连串估量写十五篇左右,目的在于帮大家捋顺JavaScript底层知识,重视教学如原型、成效域、推行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、传承等困难概念。

只要有不当也许不审慎的地方,请必需给与指正,相当多谢。假如喜欢依旧具备启迪,接待star,对小编也是后生可畏种鞭策。

本系列:

  1. JavaScirpt 深远之从原型到原型链
  2. JavaScript 深切之词法功效域和动态成效域
  3. JavaScript 深远之试行上下文栈
  4. JavaScript 深切之变量对象
  5. JavaScript 浓厚之作用域链
  6. JavaScript 浓郁之从 ECMAScript 标准解读 this
  7. JavaScript 深切之奉行上下文
  8. JavaScript 长远之闭包
  9. JavaScript 浓重之参数按值传递
  10. JavaScript 深切之call和apply的比葫芦画瓢达成

    1 赞 收藏 评论

必威 4

            } else if (document.attachEvent) {

      console.log("Hello,my name is "+this.name);

                document.attach伊芙nt("onmousemove", ?);     //this.move?怎么放进去

    },100);

            }

  }

 

}

        };

var weiqi = new Person("卫旗");

        Mouse.prototype.move = function (arg1,arg2,event) {

weiqi.getName(); 

            event = window.event || event;

//Hello,my name is pig

            var x = event.pageX || event.offsetX,

      那年输出this.name是pig,原因是this的针对是在运作函数时规定的,实际不是在概念函数时规定的,再因为setTimeout是在全局意况下只想,所以this就本着了window。

        y = event.pageY || event.offsetY;

      从前化解那个难题的方法平日是缓存this,举个例子:

            this.position = position = [x, y];

var name = "pig";

            this.log(arg1,arg2);

function Person(name){

        };

  this.name = name;

        Mouse.prototype.log = function (arg1, arg2) {

  this.getName = function(){

            console.log(arg1+","+arg2);

    //在这里边缓存三个this

            console.log(this.position);

    var self = this;

        };

    setTimeout(function(){

        new Mouse();

      //在那处是有缓存this的self

www.2cto.com

      console.log("Hello,my name is "+self.name);

地方你精通'?'号这里要干嘛了呢?笔者想给document的mousemove绑定自身的move方法,然则遭逢难点了,那样的话,Mouse.prototype.move

    },100);

里的this就不会针对Mouse的指标,相信我们日常遭遇这种难题.可能你早知道了怎么解决,不过有更加快更简便的艺术吗?答案是:

  }

  Function.prototype.bind()那么些美妙的家伙,不过ie6 7 8都不匡助,平日今世浏览器都帮衬了,我们接下去要做的正是盲目跟随大众她,

}

 这么好的艺术自然要效仿它,怎么模仿见上面nothing的原创方法

var weiqi = new Person("卫旗");

    (function () {

weiqi.getName();

            var proxy = function (fn, target) {

本文由必威发布于必威-前端,转载请注明出处:禁止转载,必威:上面你知道'

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。