一、函数
1、在JavaScript中函数分为以下几种:
普通函数 纯小写
构造函数 大驼峰命名 首字母大写
新增new.target 构造函数必须使用new来进行调用
如果使用了new关键字调用函数,返回的是函数本身
如果未使用new关键字,则返回的是undefined
function Student(name, age) {
if (new.target === undefined) {
throw new Error("please use new")
}
this.name = name;
this.age = age;
}
const stu1 = new Student("lili", 11);
console.log(stu1); // Student {name: "lili", age: 11}返回函数本身
const stu2 = Student("lili", 11);
console.log(stu2); // Uncaught Error: please use new at Student
const stu3 = Student.call(stu1, "ycx", 23); console.log(stu3); // Uncaught Error: please use new at Student
普通函数
普通函数的this指向问题
- 对象调用函数,this指向对象
var obj = {
name : "张媛",
age : 12,
lesson : "钢琴",
day : function() {
console.log(this);
}
}
obj.day(); //{name: "张媛", age: 12, lesson: "钢琴", day: ƒ}
- 直接调用函数,this指向window 在严格模式下指向undefined。
function person(name = "圆圆", age = 12, hobby = "唱歌") {
console.log(this);//window
return `${name}今年${age} 岁,平常喜欢和小伙伴一起${hobby}`;
}
var res = person();
console.log(res);
- 注意定时器和函数自执行中的this指向window
var obj = {
foo : "test",
fn : function() {
var mine = this;//这里的this指向obj this的指向赋值给mine
console.log(this.foo);//this指向obj "test"
console.log(mine.foo);//mine指向obj "test"
// 立即执行函数的this指向window
(function() {
console.log(this.foo);//undefine
console.log(mine.foo);//前面就给mine赋值obj 所以obj.foo "test"
})()
}
}
obj.fn();
- 作为构造函数 如果使用了new关键字,this指向实例化的对象
function Person(name, age) {
this.name = name;
this.age = age;
console.log(this);//Person("test",18)
}
Person.prototype.getName = function () {
console.log(this);//Person("test",18)
}
var p1 = new Person("test",18);
p1.getName();//Person("test",18) //this指向new关键字实例化出来的对象
- 如果使用了call(obj,参数1,参数2,…,参数n)、apply(obj,[参数数组])、bind,this指向绑定的对象
function count(a,b,c) {
var sum = a+b+c;
console.log(this);
}
var obj = {
name : "aimy"
};
// apply
count.apply(obj,[1,2,3]); //obj
//call
count.call(obj,1,2,3); //obj
//bind
var count1 = count.bind(obj);
count1(1,2,3); //obj
- 如果是DOM事件函数,this指向事件源
箭头函数
语法:箭头函数是一个函数表达式,理论上,任何使用函数表达式的地方都可以改成箭头函数
(参数1,参数2…) => {
函数体
}
- 如果参数只有一个,函数体只有一句话 那么参数可以省略() 返回值可以省略return 函数体省略了{}
var fn = n => 123;
- 如果箭头函数没有参数或者有多个参数,就不能省略参数中的();如果返回值有多条语句就不能省略{}和return
var fn= () => {
var i = 1;
return i++;
}
- 如果函数体内部只有一条返回语句,且返回的是一个对象,会把对象的花括号认为函数体。
解决办法:可以把返回的对象变成表达式的形式
const obj = (a, b) => ({ a: a, b: b, }) console.log(obj(1, 2));
- 箭头函数的this指向
箭头函数没有自己的this,它的this是自创建就存在的,继承自父级的执行上下文的this
var a = 5;
var obj = {
a: 1,
fn : () => {
console.log(this);//window
var that = this;
setTimeout(() => {
console.log(this.a);//5
console.log(that.a);//5
},1000)
}
}
obj.fn();
- 箭头函数注意点:
箭头函数中没有this、argument、new.target,如果要强行使用,则指向外层函数对应的this、argument、new.target
箭头函数没有原型,不在原型链中,因此占用空间非常小,不能当成构造函数来使用
var a = ()=>{
return 1;
}
console.log(a.prototype); // undefined
- 箭头函数不能作为构造函数,不能使用new
function Person(p){
this.name = p.name;
}
//如果用箭头函数作为构造函数,则如下
var Person = (p) => {
this.name = p.name;
}
- 箭头函数应用场景
临时使用的函数,并不会刻意的去调用
异步的处理函数
事件的处理
继续去沿用外层函数的this
对象的属性不要去用箭头函数,除非是特别的需求
数组方法的时候,保证代码的简洁