前端js的基础知识点(部分含简要提示)

129 阅读5分钟

js基础

  • 原始数据类型(6个)
  • typeof使用(null的值是多少)
  • boolean类型和其它类型的转换
  • Object转原始类型(tostring,valueof,[symbole.toprimitive]三个的优先级问题)
  • NaN(isNaN()函数)
  • 执行上下文,变量对象,和作用域链(三者关系)
  • 闭包(作用域链去解释)
  • 原型和原型链(prototype和prototype.construct指向,_ proto_)
  • 手写new(1.生成新对象2.arguments取出构造函数【第一个值】3.对象的原型绑定到传入的构造函数的原型4.绑定this执行构造函数【let result=construct.apply(obj,arguments)】 5.返回新对象)
function myNew(){
    let obj={};
    let construct=arguments.shift();
    obj._proto_=construct.prototype;
    if(typeof construct !='function'){
        throw new TypeError('第一个参数必须为函数')
    }
    let result=construct.apply(obj,arguments);
    return result;
}

  • instanceof(判断原型链中是否能找到类型的prototype,手写的话就是循环递归需要检测的obj的原型对象)
  • 继承的6个方式

1.原型链继承(子构造函数的prototype=父类的实例)

  • 特点:可以继承父类构造函数属性,父类原型属性
  • 缺点:1.新实例无法向构造函数传参2.继承单一3.所有新实例都共享父类实例属性

2.借用构造函数(子类的构造函数中 Super.call(this,args),call和apply将父类的构造函数引入子类构造函数中)

  • 特点:1.只继承了父类构造函数属性,没有继承父类原型属性 2.可以继承多个构造函数属性(call多个)3.子类实例中可以向父类传参
  • 缺点:1.方法都要在构造函数中定义 2.只是继承了父类的构造函数属性 3.无法实现构造函数复用 4.每个新实例都有构造函数副本

3.组合继承(原型链式继承和借用构造函数式继承同时使用)

  • 特点:可以传参可以复用,每个新的实例的构造函数都是私有的
  • 缺点:调用两次父类构造函数,子类的构造函数会代替原型上父类构造函数

原型式继承(先创建一个临时的构造函数,传入的对象作为构造函数的原型,返回这个临时类的新实例)

function content(obj){
    function F(){};
    F.prototype=obj;
    return new F();
}
  • 特点:执行了一次浅拷贝(类似Object.create())

寄生式继承(在原型式继承外面继续封装一层,在这里面添加属性和方法)


let super=new Super();
function creatAnother(obj){
    let clone=content(obj);
    clone.say=function(){
        alert('hi');
    }
    clone.name="gar";
    return clone;
}
let super2=creatAnother(super);
  • 特点:所有返回值都有say方法和name属性
  • 缺点:没有用到原型不能复用

寄生组合式继承

function inheritPrototype(subType,superType){
    let prototype=content(superType.prototype);
    prototype.constructor=subType;
    subType.prototype=protype;
}
function Sub(){
    Super.call(this)
}
//函数接收俩个参数,子类构造函数和父类构造函数
//1.创建一个超类原型的副本
//2.为创建的副本添加constructor属性指定值为子类构造函数(修复因为重写而丢失的constructor属性)
//3.将新创建的副本赋值给子类的原型

-使用寄生式继承来继承超类的原型(还要重新指定constructor),然后将结果指定给子类的原型。解决了组合式俩次调用父类构造函数问题

  • call 和apply(都是改变this指向只是参数不一样,call是参数列表,apply是数组)
  • 实现要点
  • 1.不传入第一个参数的话,就默认window 2.添加一个属性指向this 3.获取入参(去除第一个值) 4.改变this的这个属性函数执行 5.删除属性 6.返回结果

es6的继承

function MyDate(){}
MyDate.prototype.test=function(){
    return this.getTime();
}
let d=new Date()
Object.setPrototypeof(d,MyDate.prototype);
Object.setPrototypeof(MyDate.prototype,Date.prototype);
  • 思路:先创建父类的实例=>改变实例的_ proto_ 为子类的prototype=>子类的的prototype的实例_ proto_指向父类的prototype

call 的实现

Function.prototype.mycall(context){
    var context=context||window;
    context.fn=this;
    var arg=[...arguments].slice(1);
    let result=context.fn(...arg);
    delete context.fn;
    return result;
}

apply的实现

Function.prototype.myApply(context){
    var context=context||window;
    cotext.fn=this;
    var result;
    if(arguments[1]){
        result=context.fn(...arguments[1]);
    }else{
        result=context.fn();
    }
    delete context.fn;
    return result;
}

bind实现(1.使用者必须是函数2.返回是一个函数3.因为返回是函数所以可以new,所以返回值有俩个结果 附:入参和call一样是个列表)

Function.prototype.mybind(context){
    if(typeof this!='function'){
        throw new TypeError('Error')
    }
    var _this=this;
    var arg=[...arguments].slice(1);
    return Function F(){
        if(this instanceof F){
            return new _this(...args,...arguments);
        }else{
            return _this.apply(context,args.concat(arguments))
        }
    }
}

js的深浅拷贝

  • js浅拷贝(1. Object.assign({},a) 2.let b={...a})只是拷贝了第一层
  • js深拷贝
  • JSON.parse(JSON.stringify(obj)) (缺点:1.会忽略symbole和undefine 2.不能序列化函数 3.不能解决循环引用问题)
function deepClone(source){
    const result=source instanceof Array?[]:{};
    for(let keys in source){
        if(source.hasownprototype(keys){
            result[keys]=typeof  source[keys]=='object'?deepClone(source[keys]):source[keys];
        }
    }
    return result;
}

迭代方法

  • every() 所有正确才会返回true
  • filter() 返回运算后为true的数据的数组
  • forEach() 无返回单纯循环
  • map() 返回加工后的数组
  • some() 只要一个为true就为true

数组操作

  • slice() 截取返回一个新的数组
    可以存在俩个参数
    [start,end) 如果只有一个参数就是start

  • splice() 删除,插入 和替换
    第一个参数,要删除的位置
    第二个参数,要删除的项 第三个参数及以上,要替换的项
    删除 splice(0,2) 从0开始删除俩项
    插入 splice(2,0,'red') 从第二项开始开始插入red 替换 splice(2,1,'red','green') 从第二项开始删除一项并且插入red 和green