函数的三种角色
- length 形参的个数
- name:函数名
- prototype:类的原型,在原型上定义方法都是当前类实例的公有方法
- _proto:把函数当成普通对象,指向Function类的原型
function Fn(){
var num = 500;
this.x = 100;
}
Fn.prototype.getX = function(){
console.log(this.x);
}
Fn.aaa = 1000;
var f = new Fn();
f.num;
f.aaa;
var res = Fn();
- 普通函数,Fn就是一个,执行时候会形成私有作用域,然后进行形参赋值,预解析,代码执行,执行完成之后内存销毁;
- 类,有自己的实例,f就是一个Fn的作为类产生的实例,有prototype属性作为自己的原型,
- 普通对象,Fn和var obj = {}中的obj一样,都是一个普通对象,它作为对象都有一些自己的私有属性,可以通过_proto_找到Function.prototype
call
var ary = [12,23,34];
ary.slice();
ary实例通过原型链查找机制找到Array.prototype上的slice方法。
var obj = {name:'ice'};
function fn(){
console.log(this); //this->window
console.log(this.name);
}
obj.fn() //TypeError;
fn.call(obj);
call方法作用:通过原型链Function原型找到call,在执行call,让fn中this作为第一个参数obj,然后再执行。
模拟call方法
function sum(){
console.log(this);
}
function fn(){
console.log(this);
}
var obj = {name:'iceman'};
Function.prototype.myCall = function (context) {
// myCall方法中的this就是当前我要操作和改变其this关键字的那个函数名
// 1、让fn中的this关键字变为context的值->obj
// 让this这个函数中的"this关键字"变为context
// eval(this.toString().replace("this","obj"));
// 2、让fn方法在执行
// this();
};
fn.myCall(obj);// myCall方法中原来的this是fn
sum.myCall(obj);// myCall方法中原来的this是sum
function fn1() {
console.log(1);
}
function fn2() {
console.log(2);
}
fn1.call(fn2); // 1
fn1.call.call(fn2);; // 2
fn1.call(fn2):fn1通过原型链查找机制找到原型上的call方法,此时call方法中的this就是操作fn1,在call执行过程中,让fn1中的this变为fn2,在执行f1;
fn1.call(fn2):fn1通过原型链查找机制找到原型上的call方法,然后第二次找到call再执行方法,this为fn.call,this变为fn2,然后再让fn1.call执行.
call,apply,bind 区别
作用都是改变上下文
call的第一个参数将会是function改变上下文后指向的对象,如果不传,将会默认是全局对象window,第二个参数开始可以接收任意个参数,这些参数将会作为function的参数传入function,调用call的方法会立即执行
不同点:
function func (a,b,c) {}
func.call(obj, 1,2,3) // function接收到的参数实际上是 1,2,3
func.call(obj, [1,2,3]) // function接收到的参数实际上是[1,2,3],undefined,undefined
function fn() {
console.log(this);
}
fn.call(); // 普通模式下this是window,在严格模式下this是undefined
fn.call(null); // 普通模式下this是window,在严格模式下this是null
fn.call(undefined); // 普通模式下this是window,在严格模式下this是undefined
call和apply主要区别就在于apply是传递数组,而call一个一个传递。
bind有所不同,bind是事先把fn的this改成我们想要的结果。bind对应参数值不会马上执行,用到的时候执行(在ie6-8不执行);
this值绑定到bind函数上,为改变函数内部this指向,创建一个新函数为绑定函数
在react中经常使用,改变方法的this
Function.prototype.bind(thisArg [, arg1 [, arg2, …]])
onPress={this.timePlus.bind(this)}
在react中还可以用箭头函数指向
onClick={ ()=>{ this.handleClick() } }