理解函数调用
函数调用方式
1、作为函数被调用 fun()
2、作为一个对象的方法被调用 obj1.fun()
3、作为一个构造函数被调用 new fun()
4、 通过函数的apply和call方法调用 fun.call(); fun.apply()
函数声明和函数表达式的区别
函数声明
function fun1(){
console.log(this);
}
函数表达式
//匿名函数
var fun1 = function(){
console.log(this);
}
//具名函数
var fun1 = function fun2(){
console.log(this);
}
区别:
1、利用函数声明来定义的函数会被变量提升,而利用函数表达式定义的函数则会被认为是普通的变量赋值表达式,不会被变量提升。
2、利用函数声明来定义时,必须要给函数命名,而利用函数表达式定义的函数可以不用对函数进行命名。
3、在最外层使用函数声明来定义函数时,该函数可被作为全局变量被调用;而利用函数表达式定义的函数则会被当做该变量的局部变量,不能作为全局变量被调用。
示例
consloe.log(bar); //bar(){}
consloe.log(foo); //undefined
function bar(){
console.log(this);
}
var foo = function(){
console.log(this);
}
var fun1 = function fun2(){
console.log(this);
}
bar(); //Window
foo(); //Window
fun2(); //undefined
作为构造函数调用
使用关键字new调用函数会触发以下几个动作:
1、创建一个空的对象。
2、该空对象作为this参数传递给构造函数。
3、新构造的对象作为new运算符的返回值
//定义构造函数Person
function Person(){
return this;
}
var person1 = new Person();//利用new调用构造函数来创建person1对象
// var person1 = new Person()过程
var temp = {};//临时创建一个空的对象
var temp = Person.call(temp); //该空对象作为this参数传递给构造函数,创建一个新的构造对象
var person1 = temp;//新构造的对象作为new运算符的返回值
总结:
1、如果构造函数返回的是一个对象时,该对象将作为整个表达式的值返回,而传入构造函数的this将被舍弃。
2、如果构造函数返回的是一个非对象类型的值时,该对象将被忽略,返回新构建的对象。
var school = {
name: 'sise',
id: 1264
}
//定义构造函数Stu
function Stu(name){
= name;
return school;//返回一个对象
}
//定义构造函数Person
function Person(name){
= name;
return 123;//返回一个非对象类型的值
}
var stu1 = new Stu("张三");
var person1 = new Person("张三");
consloe.log(stu1);// {name: "sise", id: 1264}
consloe.log(person1);// Person {name: "张三"}
箭头函数与普通函数 this 指向的区别
箭头函数的this指向是固定的,绑定在其声明的位置;而普通函数的this指向是可变的,指向其调用位置的上下文。
var name = "window";
var obj1 = {
name: 'obj',
arrow: () => {
console.log("arrow:" + ,this);
},
func: function(){
console.log("function:" + ,this);
}
}
var obj2 = {
name: 'obj2'
}
obj1.arrow.call(obj2); //将arrow的this指向obj2 结果:arrow: window Window{}
obj1.func.call(obj2);//将func的this指向obj2 结果: func: obj2 obj2{}