1.1 构造函数
构造函数 就是 能够构造出一个对象来。
1.默认函数首字母大写。
2.构造函数 并没有显示 返回 任何东西。new 操作符 会 自动创建 给定的类型 并返回他们,当调用构造函数时,new会 自动创建this对象,且this的类型 就是构造函数类型。
3.也可以在构造函数中显示调用 return。如果返回的值是一个对象,它会代替新创建的对象实例返回。如果返回的值是一个原始类型,它会被忽略,新创建的实例会被返回。
4.因为构造函数也是函数,所以可以直接被调用,但是它的返回值为undefined,此时构造函数里面的this对象等于全局this对象。this.name其实就是创建一个全局的变量name。在严格模式下,当你补通过new 调用Person构造函数会出现错误。
{
//构造函数 ---可以创建 对象
function Person(name,age,sex){
//属性
this.name=name;
this.age=age;
this.sex=sex;
}
//实例化对象(创建对象)
var objP=new Person('tom',18,'男');
console.log(objP.name);
//创建类 ---可以创建 对象
//class Person{}
预览:
call]()和apply()方法的应用。首先,这两个函数的作用完全一样,都是调用构造函数来构造自己的对象,并且还能够改变this的指向,区别就只是传参形式不一样。
apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。
call()
call函数,能够接收两个参数一个是Object,一个是args(默认参数),这个args是一个个零散的参数,用逗号隔开。
语法:
// call() 方法
// call函数,能够接收两个参数一个是Object,一个是args(默认参数),这个args是一个个零散的参数,用逗号隔开。
// 创建 3个构造函数 (初始化对象)
//说
function Say(word,sentence){
this.word=word;
this.sentence=sentence;
}
//吃
function Eat(food,drinks){
this.food=food;
this.drinks=drinks;
}
//人
funtion Person(word,sentence,food,drinks){
//在Person构造函数中,使用call方法调用一个对象的一个方法,用另一个对象替换当前对象
// 例如:Say.call(Person, args1,args2); 即 Person对象 调用 Say对象的方法。
Say.call(this,word,sentence)
Eat.call(this,food,drinks)
}
//调用执行 构造函数 实例化对象
let xiaoma=new Person('hello','how are you','bread','milk')
console.log(xiaoma);
//获取对象的属性
console.log(xiaoma.word,xiaoma.sentence);
console.log(xiaoma.food,xiaoma.drinks);
预览:
apply() 方法
apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
// apply() 方法
//apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
// 创建 3个构造函数 (初始化对象)
//说
function Say(word,sentence){
this.word=word;
this.sentence=sentence;
}
//吃
function Eat(food,drinks){
this.food=food;
this.drinks=drinks;
}
//人
funtion Person(word,sentence,food,drinks){
//apply:调用一个对象的一个方法,用另一个对象替换当前对象
// 例如:B.apply(A, arguments);即A对象应用B对象的方法。
Say.call(this,[word,sentence])//把参数列表变成数组
Eat.call(this,[food,drinks])
}
//调用执行 构造函数 实例化对象
let xiaoma=new Person('hello','how are you','bread','milk')
console.log(xiaoma);
//获取对象的属性
console.log(xiaoma.word,xiaoma.sentence);
console.log(xiaoma.food,xiaoma.drinks);
预览:
1.2 ES6 函数扩展
函数参数的扩展
默认参数
// es5 函数的写法, 在vue中 使用es6的语法写,可以把function关键字去掉
function run1(){
return 'ok'
}
// 形参同名,但是形参中,没有一个形参是带有默认值的,这个的写法,不会报错
function fn(name,name,sex){
console.log(name,name,sex)
}
fn('tom','tom','男')
// 形参同名,但是形参中,有一个形参是带有默认值的,会报错 (这样的写法,是错误的写法)
// 报错: Uncaught SyntaxError: Duplicate parameter name not allowed in this context
function move(name,name,age=18){
console.log(name,name,age)
}
move('tom','tom',19)
只有在未传递参数,或者参数为 undefined 时,才会使用默认参数,null 值被认为是有效的值传递。
function fn(name,age=17){
console.log(name,age)
}
// 在未传递参数,才会使用默认参数
fn('lili') //lili 17
// 在 参数为 undefined 时,才会使用默认参数
fn('tom',undefined)
// 当你再传递参数的时候,你的参数设置为null值的时候,null 值被认为是有效的值传递。它会把你默认的17给覆盖掉
fn('elva',null)
函数参数默认值存在暂时性死区,在函数参数默认值表达式中,还未初始化赋值的参数值无法作为其他参数的默认值。
// 在函数参数默认值表达式中,初始化赋值的参数值 可以 作为 其他参数的默认值
// y=x 这个 就叫做 参数默认值表达式
function fn(x,y=x){
console.log(x,y)
}
fn(1)
// 在函数参数默认值表达式中,还未初始化赋值的参数值 无法 作为 其他参数的默认值 (这样的写法,是错误的写法)
function fn(x=y){
console.log(x,y)
}
fn()
不定参数
不定参数用来表示不确定参数个数,形如,...变量名,由...加上一个具名参数标识符组成。具名参数只能放在参数组的最后,并且有且只有一个不定参数。
function fn(...values){
// console.log(values)
// 对传进来的 实参,做逐一操作(遍历)
values.forEach((item)=>{
console.log(item)
})
}
// 传2个参数, 参数会被 程序 执行的时候, 放置到 函数体values数组里。
fn(1,2)
// 传3个参数, 参数会被 程序 执行的时候, 放置到 函数体values数组里。
fn(1,100,2,300)
预览:
1.3箭头函数
箭头函数提供了一种更加简洁的函数书写方式。基本语法是:
参数 => 函数体
基本用法:
当箭头函数 只有一个参数的时候,我们可以把() 圆括去掉;把{}花括号去掉。
{ // es5定义函数
function fn(v){
return v
}
console.log(fn('hi'))
// es6 箭头函数
let xy=v=>v;
console.log(xy('hello'));
}
预览:
当箭头函数没有参数或者有多个参数,要用 () 括起来。如果函数体只有一行语句,并且这条语句是要返出的(你要return返出),我们可以把{} 去掉。
function msg(){
console.log('添加成功');
}
msg()
{
//没有参数时
let msg=()=>{
console.log('添加成功');
}
msg()
}//添加成功
//当有多个参数时
let sum=(a,b)=>{
return a+b;
}
console.log(sum(5,6));
//简写
{
let sum=(a,b)=>a+b;
console.log(sum(5,6));
}//11
{
let fn3=()=>({id:1,uname:'小马',age:18})
console.log(fn3());
let obj=fn3();
console.log(obj.uname)
}
{
// 当属姓名和值相同时,可以省略不写,只留属性名
// let fn3=(id,uname,age)=>({id, uname, age})
let fn3=(id,uname,age)=>({id:id, uname:uname, age:age})
// 第一次调用
console.log(fn3(1,'小余',19));
// 第2次调用
let obj=fn3(2,'小马过河',18);
console.log(obj.uname)
}
预览:
注意点:没有 this、super、arguments 和 new.target 绑定。
// 箭头函数中的函数体里面,没有this对象,如果你在里面用this,它指向的是外层的window对象
{
let f1=()=>{
console.log(this);
}
f1()
}
// 箭头函数中的函数体里面,没有arguments对象,会报错
let f2 = ()=>{
console.log(arguments)
}
f2(60)
{
function sum(a,b,c,d){
console.log(a+b+c+d);
console.log(arguments);
}
sum(1,2,3,4)
}
预览:
箭头函数体:指的是 箭头函数中的函数体,简称 箭头函数体。
箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象。
{
function fn(){
setTimeout(() => {
console.log(this)
console.log(this.a);
}, 0);
}
// 定义全局变量
let a=20;
// 默认指向 window对象
fn()
// 定义对象
let obj={a:18}
fn.call(obj)
}//注意:这个18是对象obj里a属性上的18,和外面的全局变量a没有任何关系。
预览:
不可以作为构造函数,也就是不能使用 new 命令,否则会报错。
适合使用的场景
ES6 之前,JavaScript 的 this 对象一直很令人头大,回调函数,经常看到 var self = this 这样的代码,为了将外部 this 传递到回调函数中,那么有了箭头函数,就不需要这样做了,直接使用 this 就行。
// ES6 箭头函数 适合使用的场景
// 适合 在 回调函数中使用,它可以使 回调函数中的this 指向 对象本身。
// es5中的问题
// es5 在 回调函数中的this 指向 最外层的window对象
{
var age=20;
// 对象 = 属性 + 方法
let Person = {
'age':18,
'sayHello': function(){
setTimeout(function(){ //回调函数
console.log(this) //this 指向 最外层的window对象
console.log(this.age)
},0)
}
}
// 调用对象中的方法 写法 对象名称.方法名()
Person.sayHello() //20
}
{
var age = 20;
// 对象 = 属性 + 方法
let Person = {
'age':18,
'sayHello': function(){
setTimeout(()=>{ //回调函数
console.log(this) //this 指向 Person对象本身
console.log(this.age)
},0)
}
}
// 调用对象中的方法 写法 对象名称.方法名()
Person.sayHello() //18
}
{
// 没有出现 ES6的箭头函数的时候,我们怎么解决 回调函数中 this 指向 最外层的window对象?
var age = 20;
// 对象 = 属性 + 方法
let Person = {
'age':18,
'sayHello': function(){
//此时,函数里的this指向的是Person对象
var self = this; //解决的办法: 这样写 ,我们可以 把 这个外部this传递到回调函数中
setTimeout(function(){ //回调函数
console.log(self) //self 指向 Person对象本身
console.log(self.age)
},0)
}
}
// 调用对象中的方法 写法 对象名称.方法名()
Person.sayHello() //18
}
预览:
所以,当我们需要维护一个 this 上下文的时候,就可以使用箭头函数。
不适合使用的场景
定义函数的方法,且该方法中包含 this
var Person = {
'age': 18,
'sayHello': ()=>{
console.log(this.age);
}
};
var age = 20;
Person.sayHello(); // 20
// 此时 this 指向的是全局对象 这里代码说明的意思是 如果你在对象中的方法里 要输出 使用this,且this指向 对象本身,就不适合用箭头函数写。
var Person1 = {
'age': 18,
'sayHello': function () {
console.log(this.age);//这里的this指向的是Person1对象
}
};
var age = 20;
Person1.sayHello(); // 18
// 此时的 this 指向 Person1 对象
预览: