js基础巩固

JS知识巩固

全局类型检查

const isOfType = (() => {
    const type = Object.create(null);//创建没有原型的对象
    //  检查null类型
    type.null = x => x === null;
    //  检查undefined类型
    type.undefined = x => x === undefined;
    //  检查是否为undefined和null类型
    type.nil = x => type.null(x) || type.undefined(x);
    //检查字符串和字符串的文字类型。例如:'s', "s", `str`, new String()
    type.string = x => !type.nil(x) && (typeof x === 'string' || x instanceof String);
    // 检查数字或者数字文字类型。例如:12, 30.5, new Number()不包括NaN 和 Infinity
    type.number = x => !type.nil(x)
      && (
        (!isNaN(x) && isFinite(x)
        && typeof x === 'number'
      ) || x instanceof Number);
    // 布尔类型检查 例如:true, false, new Boolean()
    type.boolean = x => !type.nil(x) && (typeof x === 'boolean' || x instanceof Boolean);
    // 检查数组类型
    type.array = x => !type.nil(x) && Array.isArray(x);
    // 对象类型检查 例如: {}, new Object(), Object.create(null)
    type.object = x => ({}).toString.call(x) === '[object Object]';
    // 检查提供的类型实例,参数一为实例对象,参数二为类型
    type.type = (x, X) => !type.nil(x) && x instanceof X;
    // 检查变量是否为Set类的实例
    type.set = x => type.type(x, Set);
    // 检查变量是否为Map类的实例
    type.map = x => type.type(x, Map);
    // 检查变量是否为Date类的实例
    type.date = x => type.type(x, Date);
  
    return type;
  })();

检查对象里面的键

hasOwnProperty检查对象里面的键是否存在于对象且不在原型链上。

const obj = {
    props: 'value'
}

console.log('props' in obj);//true
console.log('toString' in obj);//true

console.log(obj.hasOwnProperty('props'));//true
console.log(obj.hasOwnProperty('toString'));//false

数组去重Set

let arr = [1,2,2,1,2,3,3,1,5,8,48,9]

let arr1 = new Set(arr)
// 返回的是一个对象,需要用数组转化将其转化成数组
console.log(arr1);//Set(7) {1, 2, 3, 5, 8, …}
console.log(Array.from(arr1));//1, 2, 3, 5, 8, 48, 9]

// 但是当我们对对象类型的数组去重时,却得不到结果
let arrobj = [{id:1},{id:33},{id:33},{id:2},{id:33},{id:4},{id:56},{id:33},{id:33},{id:33}]
console.log(Array.from(new Set(arrobj)));

// 这时候我们就需要使用Set类的实例方法has和add
let idSet = new Set()
arrobj.forEach(item => {
    let newId = idSet.has(item.id)//has方法是用来判断里面是否有这个值,返回的是布尔值
    console.log(newId);
    idSet.add(item.id)//add函数会检查里面是否有重复的值,没用的话才会添加
})
console.log(idSet);//Set(5) {1, 33, 2, 4, 56}

在数组遍历中使用break方法,使用some循环

我们执行数组遍历的时候一般都会使用forEach,在forEach遍历循环中我们可以实现continue的行为,只需要执行return就行。

let arr: Array<number> = [1,2,3,4,5,6,7,8,9]

arr.forEach(item => {
    if(item === 3) {
        return
    }
    console.log(item);
//1
//2
//4
//5
//6
//7
//8
//9
})

但是当我们需要实现break方法的时候forEach循环中无法实现,所以我们需要使用some循环实现

let arr: Array<number> = [1,2,3,4,5,6,7,8,9]

arr.some(item => {
    if(item === 3) {
        return false
    }

    if(item === 5) {
        return true
    }

    console.log(item);
    
})
//打印1,2,4
//在some循环中实现continue只需要return false
//想要实现break只需要return true

使用别名和默认值

function ident1({dt: data}): void {
    console.log(data);
}

ident1({
    dt: {name: 'asda', id: 50}
})
//打印{name: 'asda', id: 50}

我们可以给我们传入的对象设置别名,并且通过别名访问它

我们还可以继续细化他

function ident2({dt: {name, id = 10}}): void {
    console.log(name,id);
}

ident2({
    dt: {name: 'samle'}
})

可选链和空值合并

const obj = {
    data: {
        container: {
            name: {
                value: '1230'
            },
            init: {
                value: 0
            }
        }
    }
}
// 一般我们查询是否存在某个值的时候会
console.log(
    obj.data.container.init.value || 'have not init value'
);
// 可以看到打印的是have not init.value,但是其实是有值得所以我们需要换一种方法
console.log(
    obj.data.container.init.value ?? 'have not init value'
);//打印得是 0

const obj = {
    data: {
        container: {
            name: {
                value: '1230'
            },
            init: {
                value: 0
            }
        }
    }
}
// console.log(
//     obj.data.container.war.app.value ?? 'no value' 
// );
//上述会报错,会阻断程序得继续运行,需要层层判断才行
console.log(
    (obj && obj.data && obj.data.container && obj.data.container.war && obj.data.container.war.app && obj.data.container.war.app.value) || 'no value'
);//no value
// 我们可以看到我们写了一个十分长的判断条件,我们可以简化一下
console.log(
    obj?.data?.container?.war?.app?.value || 'no value'
);

用函数拓展类

function Parent() {
    const privateProp = 12;
    var method = () => privateProp + 1

    this.publicMethod = (x = 0) => method() + x
    this.publicProps = 10
}

class Child extends Parent {
    myProps = 20
}

let child = new Child()
console.log(child.publicMethod);//(x = 0) => method() + x
console.log(child.publicProps);//10
console.log(child.method);//undefined
console.log(child.privateProp);//undefined

可以看到在函数内部声明得都属于私有的实例属性,而使用this声明的都是可见的实例属性

拓展构造函数

先看call、apply、bind

var name = '小王',age = 17;
var obj = {
    name: '小张',
    objage: this.age,
    myFun: function() {
        console.log(this.name + this.age )
    },
    myFun1: function(city,to) {
        console.log(this.name + this.age + city + to)
    }
}
var newobj = {
    name: '小李',
    age: 99
}
obj.myFun()//小张undefined
obj.myFun.call()//指向了window,小王17
obj.myFun.apply()//指向了window,小王17
obj.myFun.bind()()//bind返回的是一个新的函数,需要执行,指向了window,小王17
obj.myFun.call(newobj)//指向了newobj。小李99
obj.myFun.apply(newobj)//指向了newobj,小李99
obj.myFun.bind(newobj)()//指向了newobj,小李99
// 第二个参数都为函数的传参
obj.myFun1.call(newobj,'珠海','深圳')//小李99珠海深圳
obj.myFun1.apply(newobj,['珠海','深圳'])//小李99珠海深圳,apply需要传入数组
obj.myFun1.bind(newobj,'珠海','深圳')()//小李99珠海深圳
obj.myFun1.bind(newobj,['珠海','深圳'])()//小李99珠海,深圳undefined   会解开数组

利用改变this的指向我们可以拓展构造函数

function func1() {
    this.name1 = '123';
    this.age = 123
}

function func2() {
    this.name2 = ['123','321']
    this.avgPerHour = '888'
}

function func3() {
    this.name3 = 'Mr wang'
    this.newobj = {};
    func1.apply(this) 
    func2.apply(this.newobj)
}

let newvalue = new func3()
console.log(newvalue);
// func3 {name3: 'Mr wang', newobj: {…}, name1: '123', age: 123}
// age: 123
// name1: "123"
// name3: "Mr wang"
// newobj: {name2: Array(2), avgPerHour: '888'}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值