js es6和异步,原型

128 阅读2分钟

es6

---------let、const、var的区别
let const块级作用域,不会变量提升和暂时性死区,必须先声明后使用
let 全局作用域,会变量提升,有暂时性死区,不声明也能使用
const 不能修改指针,let var 可以
let 声明会声明到全局对象上
const必须设置初始值

-----------const对象的属性可以修改吗
指针不能修改,如果是引用数据类型,对象里面的属性能修改

  1. 如果new一个箭头函数的会怎么样
    会报错,new 不出来,因为new需要依赖构造函数的this
    因为箭头函数没有自己的this 没有ptototype 对象

----------------- 箭头函数与普通函数的区别
写法更简洁
没有自己的this和prototype,也没有argument
this永远指向当前上下文,且不可修改

  1. 箭头函数的this指向哪里? 指向当前上下文对象的this

扩展运算符的作用及使用场景 合并数组,复制数组,将数组转为参数序列(function add(...[a,b]){})

  1. Proxy 可以实现什么功能?
    代替vue2 object.definedproperety 实现数据响应式
    进行数据代理操作,能劫持对象,自定义对象的操作

  2. 对对象与数组的解构的理解 就是通过特定的方式提取数据
    对象通过属性的名称提取
    数组通过属性的位置提取

  3. 如何提取高度嵌套的对象里的指定属性?
    const school = { classes: { stu: { name: 'Bob', age: 24, } } }
    const {classes:{stu:{name}}} = school
    console.log(name) //Bob

  4. 对 rest 参数的理解 在函数参数不确定的时候,使用rest参数,如:
    function add (a,b,...args){
    console.log(args)
    }
    add(1,2,3,4)// [3,4]

11.模板字符串比字符串拼接优势
能够在${}进行运算
能够保留换行,缩进,空格

异步

JavaScript中的异步机制可以分为以下几种:
回调函数 多个相互依赖的函数时,会进行多层嵌套,造成回调地狱
promise 解决了回调地狱的问题进行.then链式调用
generator 在generator内部进行yield同步调用,但是得手动执行
function *add(){
yield addA()
yield addB()
retrun 'end'
}
不会自动执行,得通过next()执行,如
let gn = add()
gn.next() 执行addA
gn.next() 执行addB
async await : 是generator的语法糖,实现await 同步调用,自动执行
funcion async del(){
const a =await dela()
cons b = await delb()
}
del()调用自动执行await
await 执行机制
async function async1
console.log('async1 start');
await async2(); //遇到await时先返回了,then处理后续
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
// 输出顺序:script start->async1 start->async2->script end->async1 end

promise是个立即执行函数,当在执行reslove和reject的时侯,是异步操作
console.log('script start')
let promise1 = new Promise(function (resolve) {
console.log('promise1')
resolve()
console.log('promise1 end')
}).then(function () {
console.log('promise2')
})
setTimeout(function(){
console.log('settimeout')
})
console.log('script end')
执行结果: script start,promise1,promise1 end,settimeout,promise2

Promise
异步编程的一个解决方案,是一个对象,改善了异步编程的困境,避免了回调地狱
有三个状态 padding 请求中 resolve 成功 reject 失败

promise缺点
1.无法取消一旦创建立马执行,一旦开始无法中途取消
2.不设置回调函数,promise抛出的错误不会反应到外部
3。当处于padding状态,不知道其padding进度

1.创建promise对象
//创建
let a = new promise(function (resolve,reject){
if(true){
resolve(data)
}else {
reject(err)
}
})

// 方法调用
a.then((data)=>{ }).catch((err)=>{ })

2.Promise常用方法
1.then promise正确返回
2.catch promise 错误处理
3. all 方法可以接受一个数组包含多个promise方法,返回值也是数组包含多个promise的返回值
当所有都返回resolved状态就会变为resloved,有一个reject就状态直接变为reject
Promise.all([promise1,promise2,promise3]).then(res=>{
console.log(res);
//结果为:[1,2,3]
}).catch(()=>{
如果错了一个就到catch
})

  1. race 和all方法一样接受多个promise参数,但是返回值根据第一个执行完的状态
  2. finally 方法不管promise最终结局如何,都会执行到finally

--------------------promise解决了什么问题---------------------------
解决了传统异步处理多层嵌套的回调地狱问题

  1. 对async/await 的理解 是gennerator的语法糖,优化了链式回调
    await 会阻塞跟在后面的语句 将异步变同步

  2. async/await对比Promise的优势 错误处理更友好,可以try catch
    语义化更好,比then链式调用更好阅读
    传递中间值更友好

  3. async/await 如何捕获异常(直接try catch包裹await的函数) try{ await add() }catch{ }

12.回调函数的缺点
多个函数嵌套,产生回调地狱,不好修改;
不能try catch

全局作用域和函数作用域 全局作用域: 最外层函数和变量拥有全局作用域
所有window对象的属性都属于全局作用域
所有未声明直接定义的变量,都会自动声明为全局作用域
过多的使用全局作用域会容易起冲突

函数作用域
作用域分层,外部作用域访问不了内部 函数内部声明的变量,函数外部不能访问

块级作用域
被{}包裹的代码,let ,const 属于块级作用域

最外层函数和变量拥有全局作用域
所有window对象的属性都属于全局作用域
所有未声明直接定义的变量,都会自动声明为全局作用域

作用域链
从当前作用域往上寻找,直至到window全局作用域

  1. 对执行上下文的理解
    全局执行上下文只有一个,会创建一个全局window对象

函数上下文
可以有多个,函数执行即创建

六、this/call/apply/bind
call(一个个传参数)和apply(传参数数组)都是改变函数的this,只不过传值方式不同
bind 是将this绑定的指定函数上,并返回新方法

实现call、apply 及 bind 函数
function mycall(_this){
let content = _this|| window
let canshu = [...argument].slice(1)
content.fuc = this
let reslut = conten.fuc(...canshu)
delete content.func
retrun reslut
}
function MyApply(_this){
let content = _this|| window
let canshu = argments.slice(1)
content.fuc = this
let result = null
let argument= [...argments] if(argument[1]){
result = content.fuc(...argument[1])
} else{
result = content.fuc()
}
delete content.func
return result
}
function myBInd(_this){
let bcanshu = [...arguments][1]
let fuc = this
retrun (args)=>{
retrun fn.apply(_this,bcanshu.concat(args))
}
}

new的过程 构造函数new 对象时,会将构造函数的prototype指向对象的__proto__, 这个对象包含了构造函数实例的所有属性和方法

ES5 中新增了一个 Object.getPrototypeOf() 方法,通过这个方法来获取对象的原型。

  1. 原型修改、重写 // 修改原型
    person.prototype.age = 18
    //重写原型;直接重写原型constrator执行会改变,可以改回来
    person.prototype = {age:8989}
    person.construtor = Person

  2. 原型链的终点是什么?如何打印出原型链的终点? object.prototype.proto = null

哪些情况会导致内存泄漏
意外的全局变量
闭包
忘记的定时器setinteval

for (var i = 1; i <= 5; i++) { setTimeout(function timer() { console.log(i) }, i * 1000) } 会输出什么
输出6个5
解决办法:改let,闭包。settimeout第三个参数

js面向对象

js创建对象的几种方式
1.字面量var obj = {}
2.通过new Object()
let obj = new Object() 3.通过工厂函数
function createObject(a){
let obj = {}
obj.a = a
return obj
}
4.利用构造函数
function Person(){
this.s= 's'
}
var man = new Person()

2. 对象继承的方式有哪些? 1.通过原型链继承
function father(){
this.money = '999999999'
}
function son(){
}
son.prototype = new father()

2.通过借用构造函数继承 function father(){
this.money = '999999999'
}
function son(){
father.apply(this) }
var s = new son()

3.通过class继承

class People {
constructor(name) {
this.name = name }
eat() {
console.log(${this.name} eat something) } }

// 子类继承父类 // 如果需要用到父类的属性通过super可以直接拿到

class Teacher extends People {
constructor(name,major) {
// super直接拿类定义过的值来用
super(name)
this.major = major
}
teach() {
console.log(${this.name} 教授 ${this.major}) }
}

// 实例
const zhangsan = new People('张三')
zhangsan.eat() // 张三 eat something
console.log(zhangsan.name); // 张三

3 组合继承,继承前两者的优点,能通过instanceOf和isPrototypeOf的检测
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name);//借用构造函数继承属性,二次调用
this.age = age;
} SubType.prototype = new SuperType();//借用原型链继承方法,一次调用
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age); };
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27