函数的三种角色
第一种角色:普通函数
栈内存(私有作用域)
作用域链
形参
arguments
return
…第二种角色:类
类
实例
私有和公有属性
prototype
__proto__
…第三种角色:普通对象
键值对操作
…三种角色之间没有直接的关系
1.function Fn(){2. var name='珠峰培训';3. this.age=8;4.}5.Fn.prototype.say=function(){}6.Fn.eat=function(){}7.var f = new Fn();
阿里超经典面试题(有难度)
1.function Foo() {2. getName = function () {3. console.log(1);4. };5. return this;6.}7.Foo.getName = function () {8. console.log(2);9.};10.Foo.prototype.getName = function () {11. console.log(3);12.};13.var getName = function () {14. console.log(4);15.};16.function getName() {17. console.log(5);18.}19.20.Foo.getName();21.getName();22.Foo().getName();23.getName();24.new Foo.getName();25.new Foo().getName();26.new new Foo().getName();
call apply bind
都是天生自带的方法(Function.prototype),所有的函数都可以调取这三个方法
三个方法都是改变THIS指向的
call
fn.call(context,para1,…)
把fn方法执行,并且让fn方法中的this变为context,而para1…都是给fn传递的实参
1.//=>非严格模式2.function fn(num1,num2){3. console.log(this);4.}5.var obj={fn:fn};6.fn();//=>this:window7.obj.fn();//=>this:obj8.9.var opp={};10.//opp.fn();//=>报错:opp中没有fn这个属性11.fn.call(opp);//=>this:opp num1&&num2都是undefined12.fn.call(1,2);//=>this:1 num1=2 num2=undefined13.fn.call(opp,1,2);//=>this:opp num1=1 num2=214.15.//->CALL方法的几个特殊性16.fn.call();//=>this:window num1&&num2都是undefined17.fn.call(null);//=>this:window18.fn.call(undefined);//=>this:window
1.//=>JS严格模式下2."use strict";3.fn.call();//=>this:undefined4.fn.call(undefined);//=>this:undefined5.fn.call(null);//=>this:null
apply
apply的语法和call基本一致,作用原理也基本一致,唯一的区别:apply把传递给函数的实参以数组形式存放(但是也相当于在给函数一个个的传递实参值)
1.fn.call(null,10,20,30);2.fn.apply(null,[10,20,30]); //=>传递给fn的时候也是一个个的传递进去的
bind
也是改变THIS的方法,它在IE6~8下不兼容;它和call(以及apply)改变this的原理不一样
1.fn.call(opp,10,20); //=>把fn执行,让fn中的this变为opp,并且把10&&20分别传递给fn2.3.fn.bind(opp,10,20); //=>预先让fn中的this指向opp,并且把10和20预先传递给fn,此时的fn没有被执行(只有当执行的时候this和实参才会起到应有的作用)4.5.6.//=>需求:点击box这个盒子的时候,需要执行fn,并且让fn中的this指向opp7.oBox.onclick=fn; //=>点击的时候执行了fn,但此时fn中的this是oBox8.9.oBox.onclick=fn.call(opp); //=>绑定事件的时候就已经把fn立即执行了(call本身就是立即执行函数),然后把fn执行的返回值绑定给事件10.11.oBox.onclick=fn.bind(opp);12.//=>fn.bind(opp):fn调取Function.prototype上的bind方法,执行这个方法返回了一个匿名函数13./* 14. * function(){15. * fn.call(opp);16. * }17. */18.oBox.onclick=function(){19. //=>this:oBox20. fn.call(opp);21.}
思考题
1.function fn1(){2. console.log(1);3.}4.function fn2(){5. console.log(2);6.}7.fn1.call(fn2);8.fn1.call.call.call(fn2);9.Function.prototype.call(fn2);10.Function.prototype.call.call.call(fn2);