this:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象
1.非构造函数版this
1.1
var user ="hehe";
function a(){
var user ="追梦子";
console.log(this.user); //hehe
console.log(this); //Window
}
a(); 相当于window.a(),因为window调用了a(),所以a()内的this代表window。
1.2 var o = {
user:"追梦子",
fn:function(){
console.log(this.user);//追梦子
}
}
o.fn(); o调用fn,所以this指向o
1.3 var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a);//undefined
console.log(this);//window }
}
}
var j = o.b.fn;
j(); //此时this指向window
2.构造函数版this
指向实例对象
2.1 function Fn(){
this.user = "追梦子";
}
var a =new Fn();
console.log(a.user); //追梦子 this指向a对象
2.2 function fn()
{
this.user = '追梦子';
return {name:"haha"}; //或者:return function(){};
}
var a =new fn;
console.log(a.user); //undefined
console.log(a.name); // haha
由于返回了一个新对象,这个对象不是fn构造出来的,所以不具有fn的特性;
2.3 function fn()
{
this.user = '追梦子';
return 1; //或者:return undefined;
}
var a =new fn;
console.log(a.user); //追梦子
3.call和apply
相同点:改变函数内部的this指向
不同点:接收参数方式不同
3.1 apply(obj,[argArray]), call(obj,arg1,arg2,arg3...)
function add(c,d){
return this.a + this.b + c + d;
}
var s = {a:1, b:2};
console.log(add.call(s,3,4)); // 1+2+3+4 = 10
console.log(add.apply(s,[5,6])); // 1+2+5+6 = 14
3.2 window.firstName = "Cynthia";
window.lastName = "_xie";
var myObject = {firstName:'my', lastName:'Object'};
function getName(){
console.log(this.firstName + this.lastName);
}
function getMessage(sex,age){
console.log(this.firstName + this.lastName + " 性别: " + sex + " age: " + age );
}
getName.call(window); // Cynthia_xie
getName.call(myObject); // myObject
getName.apply(window); // Cynthia_xie
getName.apply(myObject);// myObject
getMessage.call(window,"女",21); //Cynthia_xie 性别: 女 age: 21
getMessage.apply(window,["女",21]); // Cynthia_xie 性别: 女 age: 21
getMessage.call(myObject,"未知",22); //myObject 性别: 未知 age: 22
getMessage.apply(myObject,["未知",22]); // myObject 性别: 未知 age: 22
4.Bind
改变函数的this指向不同的是产生了新的函数对象
var bar= function(){
console.log(this.x);
}
varfoo={
x:3
}
bar() //undefined
bar.bind(foo)()//3
5.argument
1、我们可以借用arguments.length可以来查看实参和形参的个数是否一致:
function add(a,b){
var reallyLen = arguments.length; //实参
console.log("really arg len",reallyLen);
var funcLen = add.length; //形参
console.log("func arg len",funcLen);
}
add(1,2,3,4,5)
// [Log] really arg len – 5
// [Log] func arg len – 2
2.我们可以借用arguments.callee来让匿名函数实现递归:
var sum = function(n) {
if(n == 1) {
return 1;
}else {
return n + arguments.callee(n-1);
}
}
console.log("sum =", sum(5));