由此我们可以首先得出 bind 函数的两个特点,举
分类:巴黎人-前端

类数组对象

所谓的类数组对象:

具备贰个 length 属性和若干索引属性的目的

比如:

var array = ['name', 'age', 'sex']; var arrayLike = { 0: 'name', 1: 'age', 2: 'sex', length: 3 }

1
2
3
4
5
6
7
8
var array = ['name', 'age', 'sex'];
 
var arrayLike = {
    0: 'name',
    1: 'age',
    2: 'sex',
    length: 3
}

尽管如此,为何叫做类数组对象啊?

那让大家从读写、获取长度、遍历几个方面看看那多少个对象。

仿照完结率先步

那就是说我们该怎么模拟完结那四个效能呢?

试想当调用 call 的时候,把 foo 对象改换成如下:

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

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

其不时候 this 就针对了 foo,是或不是很轻易吗?

不过这样却给 foo 对象自己增添了贰个属性,那可不行呀!

只是也不用惦记,大家用 delete 再删除它不就好了~

所以我们模拟的步调能够分为:

  1. 将函数设为对象的属性
  2. 推行该函数
  3. 剔除该函数

如上个例证为例,正是:

// 第一步 foo.fn = bar // 第二步 foo.fn() // 第三步 delete foo.fn

1
2
3
4
5
6
// 第一步
foo.fn = bar
// 第二步
foo.fn()
// 第三步
delete foo.fn

fn 是目的的属性名,反正最终也要删减它,所以起成什么样都不留意。

依照那么些思路,我们得以品味着去写第一版的 call2 函数:

// 第一版 Function.prototype.call2 = function(context) { // 首先要拿走调用call的函数,用this能够博得 context.fn = this; context.fn(); delete context.fn; } // 测验一下 var foo = { value: 1 }; function bar() { console.log(this.value); } bar.call2(foo); // 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 第一版
Function.prototype.call2 = function(context) {
    // 首先要获取调用call的函数,用this可以获取
    context.fn = this;
    context.fn();
    delete context.fn;
}
 
// 测试一下
var foo = {
    value: 1
};
 
function bar() {
    console.log(this.value);
}
 
bar.call2(foo); // 1

恰恰能够打印 1 哎!是或不是非常的慢乐!(~ ̄▽ ̄)~

(๑•̀ㅂ•́)و✧
模仿达成第三步
仿照代码已经到位 百分之七十,还应该有五个小点要注意:
1.this 参数可以传 null,当为 null 的时候,视为指向 window
举个例证:
var value = 1;function bar() { console.log(this.value);}bar.call(null); // 1

哪些在浏览器中运作JavaScript?
  • <script> console.log('运行JS') </script>
  • <script src='./*'> </script>

构造函数效果的效仿完成

成功了这两点,最难的片段到啊!因为 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深切之从原型到原型链》。

遍历

for(var i = 0, len = array.length; i len; i++) { …… } for(var i = 0, len = arrayLike.length; i len; i++) { …… }

1
2
3
4
5
6
for(var i = 0, len = array.length; i  len; i++) {
   ……
}
for(var i = 0, len = arrayLike.length; i  len; i++) {
    ……
}

是或不是很像?

那类数组对象足以运用数组的办法吧?比方:

arrayLike.push('4');

1
arrayLike.push('4');

而是上述代码会报错: arrayLike.push is not a function

据此毕竟依然类数组呐……

call

一句话介绍 call:

call() 方法在动用三个点名的 this 值和多少个钦命的参数值的前提下调用有些函数或方法。

举个例子:

var foo = { value: 1 }; function bar() { console.log(this.value); } bar.call(foo); // 1

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

留心两点:

  1. call 改变了 this 的指向,指向到 foo
  2. bar 函数试行了

宪章达成率先步
那便是说大家该怎么模拟完成那八个职能呢?
试想当调用 call 的时候,把 foo 对象改动成如下:
var foo = { value: 1, bar: function() { console.log(this.value) }};foo.bar(); // 1

规格语句
  • if语句
if(true){
console.log('我被执行了')
}else{
console.log('我永远不会被执行')
}
  • switch语句
var f = 'apple';
if(f ==='banana'){
console.log('banana')
}else if(f==='apple'){
console.log('apple')
}
//多个if(){}else if{}嵌套时使用switch语句
switch(f){
case 'banana' : console.log('banana');
break;
case 'apple':console.log('apple');
break;
default: console.log('default');
}
  • 三朝运算符

    - expression ? do(true): do(false);

 let a = false;
 let b = a ? 1:2;
 console.log(b) // 2;
}```

- while循环语句
 - 

{
let i = 0;
while(i<10){
console.log(i); //0~9
i++;
}
}
{
let i = 11;
do{
console.log(i);
i--;
}while(i<10);
}

- for循环语句

for(let i=0;i<100;i++){
console.log(i);//0~99
}

- break和continue关键字

{
for(let i=0;i<10;i++){

if(i>=5){break;}   
 console.log(i); //0~4

}
}
{
for(let i=0; i<10;i++){
if(i<=5){continue;}
console.log(i);// 6~9
}
}

##### 数据类型
- 数值(number)
- 字符串(string)
- 布尔值(boolean) 
 - 5个假值(null,undefined,0,'',NaN)
- undefined
- null
- 对象(object)
  - 数组(Array)  是一种对象
  - 函数(Function) 是一种对象
  - 普通对象  

##### 类型转换

{
let number = 1;
let string = number+'';
console.log(typeof string,string) //string,"1"
}
{
let number = 1;
let bool =!number;
console.log(typeof bool,bool) //boolean,false
}
{
let string = '123';
//let number = string -0;
let number = +string;
console.log(typeof number,number) //number,123
}
{
let string = 'hello';
let number = string - 0;
console.log(typeof number,number) //NaN;
}
{
let bool = true;
let number = bool -0;
//let number = !bool -0; number, 0
console.log(typeof number,number) //number,1
}

- ##### 字符串方法以及遍历
  - ES5

//遍历
{
let string = "hello";
for(let i = 0;i<string.length;i++){

console.log(string[i])

}
}
//method
{
let str = 'hello';
let newStr = str.substring(1,2); // [start,end)
console.log(str); // 'hello'
console.log(newStr) // 'e'
}
{
let str = 'world';
let newStr = str.substr(1,2); //start, deleteCount
console.log(str); // 'world'
console.log(newStr) // 'or'
}

- ES6

{
let string = "world";
for(let i of string){
console.log(i)
}
}

 ##### 声明对象以及读写属性、遍历对象
- Obejct是一种无序的集合
 - ES5

{
let o = {
name:'小花',
age:18,
skill: function(){console.log('say')}
};
/*let o = new Object({
name:'小花'
}) */
console.log(o.name); //"小花"
o.name = '小草';
console.log(o['name']);//"小草"
console.log('name' in o); //true
delete o.name; //o = {};
}
{
let o = {
name:'小草',
age:18
}
for(let i in o){
console.log(i); //name,age
console.log(o[i]); //小草,18
}
}

 - ES6

{
let name = 'xiaohua',age = 16;
let o = {
name,
age,
skill(){
console.log('say')
}
}
console.log(o.skill())
}
{
let a = 'b';
let es5_obj = {
a:'c',
b:'c'
}
let es6_obj ={
[a]:'c' //key可以用变量
}
console.log(es5_obj,es6_obj);
}

##### 声明数组、遍历数组
- Array是一种有序的集合

- 数组的一些方法
  - ES5

{
let array = [1,2,3,[4,5,6],{5:"6",6:"7",7:"8"}]; //评释数组
console.log(array);
console.log(array.length);//5;
for(let i = 0; i<array.length;i++){
console.log(i,"-",array[i]);
}
array.push(9,10,11,[12,13,14],{name:"array"});
console.log(array);
array.pop();
console.log(array.length);
}
{
let arr = [2,3,1,4,5];
arr.sort();
console.log(arr);//[1,2,3,4,5]
arr.sort(function(a,b){return a<b});
console.log(arr);//[5,4,3,2,1]
}
{
let arr = [1,2,3,4,5];
let deleteArr = arr.splice(0,2,0,1,2);//array.splice(start, deleteCount, item1, item2, ...)
console.log(arr);
console.log(deleteArr);
}
{
let arr = [1,2,3,4];
let arrStr = arr.join('--');
console.log(arr);
console.log(arrStr);
let newArrStr = arrStr.split('--');
console.log(newArrStr);
}

  - ES6

{ //将伪数组调换到数组
function arg(){
argArray = Array.from(arguments,(item)=> item2); //Array.from(arrayLike[, mapFn[, thisArg]])
console.log(argArray)
}
/

argArray = Array.from(arguments);
argArray.forEach(function(item){console.log(item)})
*/
arg(1,2,3,4,5)
}
{ //填充数组
let array = [1,2,3,4,5]; //arr.fill(value) arr.fill(value, start) arr.fill(value, start, end)
newArray = array.fill(0);
console.log(newArray);
console.log(array);
console.log(array.fill(9,0,3));
console.log(array);
}
{ //遍历数组
let array = [1,2,3,4,5];
for(let i of array){
console.log(i) //1,2,3,4,5
}
for(let i of array.keys()){
console.log(i)//0,1,2,3,4
}
for(let [i,v] of array.entries()){
console.log(i,v)
}
console.log(array.find((item)=>item>3)); //查找满意条件,只回去第二个
console.log(array.findIndex(item=>item>3));
{
let array = [1,2,3,4,5];
console.log(array.includes(1,0))//arr.includes(searchElement, fromIndex) //是还是不是含有
}
}

##### 声明函数,函数提升,arguments及...rest,length属性,闭包,同步V.S.异步
 - ES5

// var say = function(){}; 只会晋级var say
function say(x){ //提高整个函数
console.log(x);
console.log(arguments) //将传入全数实参生成八个伪数组,其实是多少个key为平稳下标的靶子
return x //使函数具备重回值
}
say('hello'); //传入实参
console.log(say.length);//行参个数
var c =say('hello'); //再次回到值赋予变量c
console.log(c);
{ //立刻执行函数 幸免全局污染
!function(){
var a = 1;
console.log(a)
}();
!function(){
var a = 2;
console.log(a)
}();
}
{ //闭包
function f1(){
var a = 1;
function f2(){
a++;
console.log(a)
}
return f2;
}

let result = f1();
result();
}
{//同步
console.log(1);
console.log(2);
console.log(3);
}
{//异步
console.log(1);
setTimeout(function(){
console.log(2);
},3000)
console.log(3);
}

 - ES6

{ //ES6留存块及效能域,无需利用佚名函数来卫戍全局污染
let a =1 ;
console.log(a);
}
{
let a = 2;
console.log(a);
}
{
function say(x,y = 'world'){ //行参暗许值
console.log(x,y);
}
say('hello');
}
{
let say = (...arg)=>{
console.log(arg);
for(let i of arg){
console.log(i);
}
console.log(typeof arg.push) //那是贰个真数组,和arguments分化
}
say('hello','world');
}
{
let x = 'china';
let say = (x,y = x)=>{
console.log(x,y);
}
say('hello');//"hello hello"
}
{
let x = 'china';
let say = (z,y = x)=>{ //变量功效域,和上多少个例证比较
console.log(z,y);
}
say('hello');//"hello china"
}
{
let say = (x)=> x ;//此处假如加{}就不会有重回值
/*
var say = function(x){
return x
}
*/
let result = say(100);
console.log(result)
}
{ //函数作为重回值,函数作为参数的事例
let qux= ()=> (callback)=> callback();
let result = qux();
console.log(result);
result(()=>{console.log("执行了")})
}

类、原型、继承(面向对象)
  - ES5

{
function Person(name,age,gender){
this.name = name;
this.age =age;
this.gender = gender;
}
Person.prototype.born = function(){
console.log('born')
}
function Man(){
Person.apply(this,arguments)
this.sex = 'male'
}
let empty = function(){};
empty.prototype = Person.prototype;
Man.prototype = new empty();
console.log(Man.prototype.constructor = Man);
var man1 = new Man('张三',18,'male');
console.log(man1)
}
{
var name,age,gender;
var Person = {
name:name,
age:age,
gender:gender,
born:function(){console.log('born')}
}
var Man = Object.create(Person);
Man.sex = 'male';
console.log(Man)
}

  - ES6 

{//ES6 类
class Person{
constructor(name='张三',age= 18,gender='male'){
this.name = name;
this.age =age;
this.gender = gender;
};
born(){
console.log('born')
};
die(){
console.log('die')
}
}
console.log(new Person)
class Man extends Person{//类的存在延续
constructor(){
super();
this.sex = 'Man'
}
}
let man1 = new Man()
console.log(man1)
console.log(man1.born())
}

##### 标准库
 - Array
 - String
 - Number
 - Function
 - Boolean
 - Math(console.dir(Math)  )
  - Math.PI;              //3.141592653589793
  - Math.SQRT2;      //1.4142135623730951
  -Math.pow();
  -Math.sqrt(); 
  - Math.random()*50+50 ;// 50~100之间的伪随机数
 - Date
  - new Date() 
    - 
       ```
{
let date = new Date();
  console.log(date);//Sat Jun 03 2017 01:27:41 GMT+0800 (CST)
  console.log(date.getFullYear())  //2017
  console.log(date.getMonth()) // 5   0~11个月
  console.log(date.getDate())  //3    
  console.log(date.getDay())  //6 星期日为0,星期一为1。
  console.log(date.getHours());
  console.log(date.getMinutes())
  console.log(date.getSeconds())
}
  • toLocaleString()

  • Promise

{
  function breakfast(callback){
     console.log('吃早饭');
     callback&&callback();
  }
  function lunch(){
     console.log('吃午饭');
  }
  console.log(breakfast(lunch))
}
{
  let breakfast = function(){
    console.log('吃早饭');
    return new Promise(function(resolve,reject){
      resolve();
    })
  } 
  let lunch = function(){
    console.log('吃午饭');
    return new Promise(function(resolve,reject){
     resolve();
    })
  }
  let dinner = function(){
    console.log('吃晚饭')
  }
 breakfast().then(lunch).then(dinner)
}

深深种类

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 赞 收藏 评论

图片 1

传递参数

将参数从贰个函数传递到另贰个函数

// 使用 apply 将 foo 的参数字传送递给 bar function foo() { bar.apply(this, arguments); } function bar(a, b, c) { console.log(a, b, c); } foo(1, 2, 3)

1
2
3
4
5
6
7
8
9
// 使用 apply 将 foo 的参数传递给 bar
function foo() {
    bar.apply(this, arguments);
}
function bar(a, b, c) {
   console.log(a, b, c);
}
 
foo(1, 2, 3)

JavaScript 深入之call和apply的模拟完毕

2017/05/25 · JavaScript · apply, call

初稿出处: 冴羽   

可是都很好消除,让大家一直看第三版也正是最后一版的代码:
// 第三版Function.prototype.call2 = function (context) { var context = context || window; context.fn = this; var args = []; for(var i = 1, len = arguments.length; i < len; i++) { args.push('arguments[' + i + ']'); } var result = eval('context.fn(' + args +')'); delete context.fn return result;}// 测量检验一下var value = 2;var obj = { value: 1}function bar(name, age) { console.log(this.value); return { value: this.value, name: name, age: age }}bar.call(null); // 2console.log(bar.call2(obj, 'kevin', 18));// 1// Object {// value: 1,// name: 'kevin',// age: 18// }

JavaScript 变量表明升高
  • ES5
console.log(a); //undefind
var a = 1;
//等同如下
var a;
console.log(a);  //undefind
a = 1;
  • ES6:let注脚变量不升官
console.log(a); // ReferenceError: a is not defined
let a = 1;

末段代码

为此最末尾的代码正是:

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;
 
}

读写

console.log(array[0]); // name console.log(arrayLike[0]); // name array[0] = 'new name'; arrayLike[0] = 'new name';

1
2
3
4
5
console.log(array[0]); // name
console.log(arrayLike[0]); // name
 
array[0] = 'new name';
arrayLike[0] = 'new name';

仿照落成第三步

如法泡制代码已经做到 五分之四,还应该有三个小点要专一:

1.this 参数能够传 null,当为 null 的时候,视为指向 window

举个例证:

var value = 1; function bar() { console.log(this.value); } bar.call(null); // 1

1
2
3
4
5
6
7
var value = 1;
 
function bar() {
    console.log(this.value);
}
 
bar.call(null); // 1

虽说这一个例子自身不利用 call,结果还是同样。

2.函数是能够有再次回到值的!

举个例证:

var obj = { value: 1 } function bar(name, age) { return { value: this.value, name: name, age: age } } console.log(bar.call(obj, 'kevin', 18)); // Object { // value: 1, // name: 'kevin', // age: 18 // }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var obj = {
    value: 1
}
 
function bar(name, age) {
    return {
        value: this.value,
        name: name,
        age: age
    }
}
 
console.log(bar.call(obj, 'kevin', 18));
// Object {
//    value: 1,
//    name: 'kevin',
//    age: 18
// }

只是都很好解决,让我们直接看第三版也便是最后一版的代码:

// 第三版 Function.prototype.call2 = function (context) { var context = context || window; context.fn = this; var args = []; for(var i = 1, len = arguments.length; i len; i++) { args.push('arguments[' + i + ']'); } var result = eval('context.fn(' + args +')'); delete context.fn return result; } // 测验一下 var value = 2; var obj = { value: 1 } function bar(name, age) { console.log(this.value); return { value: this.value, name: name, age: age } } bar.call(null); // 2 console.log(bar.call2(obj, 'kevin', 18)); // 1 // Object { // value: 1, // name: 'kevin', // age: 18 // }

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 第三版
Function.prototype.call2 = function (context) {
    var context = context || window;
    context.fn = this;
 
    var args = [];
    for(var i = 1, len = arguments.length; i  len; i++) {
        args.push('arguments[' + i + ']');
    }
 
    var result = eval('context.fn(' + args +')');
 
    delete context.fn
    return result;
}
 
// 测试一下
var value = 2;
 
var obj = {
    value: 1
}
 
function bar(name, age) {
    console.log(this.value);
    return {
        value: this.value,
        name: name,
        age: age
    }
}
 
bar.call(null); // 2
 
console.log(bar.call2(obj, 'kevin', 18));
// 1
// Object {
//    value: 1,
//    name: 'kevin',
//    age: 18
// }

到此,大家做到了 call 的模拟达成,给自身三个赞 b( ̄▽ ̄)d

恰好能够打字与印刷 1 哎!是还是不是很欢腾!(~ ̄▽ ̄)~
宪章达成第二步
最一同初也讲了,call 函数还是可以够给定参数实践函数。比如:
var foo = { value: 1};function bar(name, age) { console.log(name) console.log(age) console.log(this.value);}bar.call(foo, 'kevin', 18);// kevin// 18// 1

注释
  • 单行:/那是注释/。
  • 多行:/*那是注释*/。

回来函数的上行下效完毕

从第叁个特征伊始,大家比如:

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);
    }
 
}

本文由巴黎人手机版发布于巴黎人-前端,转载请注明出处:由此我们可以首先得出 bind 函数的两个特点,举

上一篇:没有了 下一篇:没有了
猜你喜欢
热门排行
精彩图文