JavaScript一些问题


箭头函数

箭头函数表达式的语法比函数表达式更简洁,并且没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

没有单独的this

在箭头函数出现之前,每一个新函数根据它是被如何调用的来定义这个函数的this值:

  • 如果是该函数是一个构造函数,this指针指向一个新的对象
  • 在严格模式下的函数调用下,this指向undefined
  • 如果是该函数是一个对象的方法,则它的this指针指向这个对象
  • 等等

This被证明是令人厌烦的面向对象风格的编程。

箭头函数表达式对非方法函数是最合适的。

 

prototype _proto_ constructor 原型链和原型对象

所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法。

使用对象的构造器(constructor):

 function Person(first, last, age, eyecolor) {
    this.firstName = first;  
    this.lastName = last;  
    this.age = age;  
    this.eyeColor = eyecolor;
 }
 var myFather = new Person("John", "Doe", 50, "blue");
 var myMother = new Person("Sally", "Rally", 48, "green");

在一个已存在的对象构造器中是不能添加新的属性的:

 Person.nationality = "English";//不可行

要添加一个新的属性需要在在构造器函数中添加:

 function Person(first, last, age, eyecolor) {
    this.firstName = first;  
    this.lastName = last;  
    this.age = age;  
    this.eyeColor = eyecolor;  
    this.nationality = "English";
 }

原型链

JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

__proto__ 属性,它是对象所独有的,可以看到__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象(也可以理解为父对象)。直到原型链顶端null。

通过__proto__属性来连接对象直到null的一条链即为我们所谓的原型链。

添加属性和方法

有的时候我们想要在所有已经存在的对象添加新的属性或方法。

另外,有时候我们想要在对象的构造函数中添加属性或方法。

使用 prototype 属性就可以给对象的构造函数添加新的属性:

 function Person(first, last, age, eyecolor) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eyecolor;
 }
 Person.prototype.nationality = "English";

当然我们也可以使用 prototype 属性就可以给对象的构造函数添加新的方法:

 function Person(first, last, age, eyecolor) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eyecolor;
 }
 Person.prototype.name = function() {
    return this.firstName + " " + this.lastName;
 };

constructor

constructor属性也是对象才拥有的,它是从一个对象指向一个函数,含义就是指向该对象的构造函数

注意:

利用prototype重写构造函数后,constructor会指向你重新写的这个构造函数对象。

 function Person(first, last, age, eyecolor) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eyecolor;
 }
 Person.prototype = {
    getName: function() {
    return this.firstName + " " + this.lastName;
  };
 }
   

就像是这个实例,重写后会指向:

  function() {
    return this.firstName + " " + this.lastName;
 };

这个构造函数对象。

所以在重写prototype之后,要将constructor重新写回原构造对象

  Person.prototype = {
     constructor :Person;
    getName: function() {
    return this.firstName + " " + this.lastName;
  };
 }

this关键字

面向对象语言中 this 表示当前对象的一个引用。

但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。

  • 在方法中,this 表示该方法所属的对象。
  • 如果单独使用,this 表示全局对象。
  • 在函数中,this 表示全局对象。
  • 在函数中,在严格模式下,this 是未定义的 (undefined)。
  • 在事件中,this 表示接收事件的元素。

promise

  • promise是一个对象,对象和函数的区别就是对象可以保存状态,函数不可以(闭包除外)
  • 并未剥夺函数return的能力,因此无需层层传递callback,进行回调获取数据
  • 代码风格,容易理解,便于维护
  • 多个异步等待合并便于解决

promise详解

 new Promise(
   function (resolve, reject) {
     // 一段耗时的异步操作
     resolve('成功') // 数据处理完成
     // reject('失败') // 数据处理出错
  }
 ).then(
  (res) => {console.log(res)},  // 成功
  (err) => {console.log(err)} // 失败
 )

  • resolve作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去; reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
  • promise有三个状态: 1、pending[待定]初始状态 2、fulfilled[实现]操作成功 3、rejected[被否决]操作失败 当promise状态发生改变,就会触发then()里的响应函数处理后续步骤; promise状态一经改变,不会再变。
  • Promise对象的状态改变,只有两种可能: 从pending变为fulfilled 从pending变为rejected。 这两种情况只要发生,状态就凝固了,不会再变了。

最简单示例:

 new Promise(resolve => {
   setTimeout(() => {
     resolve('hello')
  }, 2000)
 }).then(res => {
   console.log(res)
 })

分两次,顺序执行

 new Promise(resolve => {
     setTimeout(() => {
       resolve('hello')
    }, 2000)
  }).then(val => {
     console.log(val) // 参数val = 'hello'
     return new Promise(resolve => {
       setTimeout(() => {
         resolve('world')
      }, 2000)
    })
  }).then(val => {
     console.log(val) // 参数val = 'world'
  })

promise完成后then()

 let pro = new Promise(resolve => {
    setTimeout(() => {
      resolve('hello world')
    }, 2000)
  })
  setTimeout(() => {
    pro.then(value => {
    console.log(value) // hello world
  })
  }, 2000)

结论:promise作为队列最为重要的特性,我们在任何一个地方生成了一个promise队列之后,我们可以把他作为一个变量传递到其他地方。

asyncawait是如何处理异步任务的?

简单说,async是通过Promise包装异步任务。

比如有如下代码:

 async function async1() {
   await async2()
   console.log('async1 end')
 }
 async function async2() {
   console.log('async2 end')
 }
 async1()

改为ES5的写法:

 new Promise((resolve, reject) => {
   // console.log('async2 end')
   async2()
   ...
 }).then(() => {
  // 执行async1()函数await之后的语句
   console.log('async1 end')
 })

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值