call() call()的使用方法
语法:function.call(thisObj, arg1, arg2, …)
说明:call()
方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果提供的thisObj参数为null
或undefined
时会自动替换为指向全局对象,原始值会被包装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function Class1 ( ) { this .name = "class1" ; this .showName = function ( ) { console .log(this .name); } } function Class2 ( ) { this .name = "class2" ; } var c1 = new Class1();var c2 = new Class2();c1.showNam.call(c2);
call()
的意思是把c1的方法放到c2上执行,原来c2是没有showName()方法的,现在把c1的showName方法放进c2里执行,所以this.name应该是class2,执行的结果就是’class2’;call()
方法实现继承
1 2 3 4 5 6 7 8 9 10 11 function Class1 ( ) { this .showTxt = function ( ) { console .log(txt) } } function Class2 ( ) { Class1.call(this ); } var c2 = new Class2()c2.showTxt('cc' )
这样Class2就继承Class1了,Class1.call(this)的意思就是使用Class1对象代替this对象,那么Class2中就可以有了Class1的所有属性和方法了,c2对象就能够直接调用Class1的方法及属性,执行结果就是console.log(‘cc’); 使用call()
继承的弊端: 如果Class1后续向prototype
添加了新的属性或方法,Class2拿不到新增的属性和方法
1 2 Class1.prototype.name = 'class1' console .log(c2.name)
call()原理 js实现call
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 function person (a, b, c, d ) { return { name : this .name, a : a, b : b, c : c, d : d } } var yx = { name : 'yx' }; Function .prototype.newCall = function (obj, ...args ) { var obj = obj || window ; obj.p = this ; var newArgs = []; for (var i = 0 ; i < args.length; i++) { newArgs.push('args[' + i + ']' ) } var result = eval ('obj.p(' + newArgs + ')' ) delete obj.p; return result } var bib = person.newCall(yx, '1' , '2' , '3' , '4' ) console .log(bib);
apply() apply()的使用方法
语法: function.apply(thisArg, [argArr])
说明: apply()
方法与call()
方法类似。也是改变this指向(函数执行时所在的作用域),然后在指定的作用域中,调用该函数,同时也会立即执行该函数。唯一的区别在于,apply()接受一个数组作为执行时的参数。
1 2 3 4 5 6 7 var obj = { name :'yx' }; function test (firstName,lastName ) { console .log(firstName + ' ' + this .name + ' ' + lastName); } test.apply(obj,['a' ,'b' ])
apply()原理 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 function person (a,b,c,d ) { return { name : this .name, a :a,b :b,c :c,d :d } } var yx = { name : 'yx' } Function .prototype.newApply = function (obj, arr ) { var obj = obj || window , result; obj.p = this ; if (!arr){ result = obj.p() }else { var newArgs = []; for (var i=0 ; i<arr.length; i++){ newArgs.push('arr[' + i +']' ) } result = eval ('obj.p(' + newArgs +')' ) } delete obj.p return result; } var res = person.newApply(yx,['a' ,'b' ,'c' ,'d' ]);
bind() bind()使用方法
语法: function.bind(thisArg, arg1, arg2, …)
说明: bind()
方法主要就是将函数绑定到某个对象,bind()
会创建一个函数,函数体内的this对象的值会被绑定到传入bind()
中的第一个参数的值,例如:f.bind(obj),实际上可以理解为obj.f(),这时f函数体内的this自然指向的是obj
1 2 3 4 5 6 7 8 9 10 this .num = 9 ;var moduleA = { num :81 , getNum (){ return this .name } } var getNum = moduleA.getNumgetNum() var boundGetNum = getNum.bind(moduleA)boundGetNum();
bind()原理 1 2 3 4 5 6 7 8 9 Function .prototype.newBind = function ( ) { const that = this ; var args = Array .prototype.slice.call(arguments ); var context = args.shift(); return function ( ) { var arrSum = args.concat([...arguments]) return that.apply(context, arrSum) } }