前端开发核心知识进阶 1.4 JavaScript高频考点及基础题库

一、JavaScript数据类型及其判断

1.使用typeof判断数据类型

 规律:返回值为字符串,基本数据类型返回对应的基本数据类型,复杂数据类型只会返回object和function,null返回object,虽然typeof null为object,但这只是JavaScript 存在的一个悠久 Bug,不代表null就是引用数据类型,并且null本身也不是对象

2.使用instanceof判断数据类型

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

例:

function Fn(a){
    this.a = a
}
f = new Fn('a')
console.log(f.__proto__ === Fn.prototype); //true
console.log(f.__proto__.__proto__ === Object.prototype); //true
console.log(f instanceof Fn); //true
console.log(f instanceof Object); //true
console.log(5 instanceof Number); //false
console.log(new Number(5) instanceof Number); //true

上述代码中,5是基本类型不是对象,所以返回false,new Number(5)是对象,所以返回true。

Object在f对象的原型链上,所以instanceof返回true

下面实现一下instanceof

function newInstance(obj,ctor){
    if(typeof obj !== 'object'){
        return false
    }
    while(1){

        if(ctor === null){
            return false
        }

        if(obj.__proto__ === ctor.prototype){
            return true
        }
        obj = obj.__proto__
    }
}

function Fn(a){
    this.a = a
}
f = new Fn('a')
console.log(newInstance(f,Fn)); //true
console.log(newInstance(f,Object)); //true

3、使用constructor和Object.prototype.toString判断数据类型

console.log(Object.prototype.toString.call(1)); //[object Number]
console.log(Object.prototype.toString.call('1')); //[object String]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(Symbol('1')));//[object Symbol]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call({}));//[object Object]

Object.prototype.toString是万能方法,什么类型都能判断,通过slice(8,-1))就可以拿到大写开头的数据类型了

console.log(Object.prototype.toString.call(1).slice(8,-1)); //Number

constructor返回变量的构造函数,但是null和undefined类型会报错

var a = 5
console.log(a.constructor); //[Function: Number]

二、JavaScript数据类型及其转换


JavaScript是一种弱类型,或者说是一个动态语言,不用声明变量的数据类型,在程序运行中,变量的数据类型会被自动确定

例:

console.log(1 + '1'); //11
console.log('1' + true); //1true
console.log(1 + true); //2
console.log(1 + undefined); //NaN
console.log(1 + null); //1
console.log(1 + true); //2
console.log(1 + false); //1
console.log({} + true); //[object Object]true

由以上例子可得出规律:string类型和其他数据类型相加时,其他数据类型会转成string类型。其他情况都会转成number类型,undefined类型会转成NaN,相加结果为NaN,true转为1,false转为0.

如果相加俩侧存在复杂类型,复杂类型会转成基本类型,再进行计算。

在转换时会用对象的valueOf或toString方法,这俩方法的返回值为转换的结果。具体用哪个方法,从主观上说,这个对象倾向转成什么,就优先调用哪个方法,对象倾向转为string类型就用toString方法,倾向转为number类型就调用valueOf方法。

valueOf和toString是可以被开发者重写的

const obj = {
    toString(){
        return '1'
    },
    valueOf(){
        return 1
    }
}
console.log(2 + obj); //3
console.log('2' + obj); //21

可以看到与字符串相加时,调用了toString,与数字相加时调用了valueOf

三、JavaScript函数参数传递


先看个例子

var foo = {n:1};
var a = 1

function fan(foo,a){

	console.log(foo.n); //1
    foo.n = 2
    a = 2
	foo = {}
    foo.n = 3
	console.log(foo); //{ n: 3 }
}
fan(foo,a)
console.log(foo.n,a); //2 1

如果参数是基本类型,会在函数体内复制一份参数值,不会影响原参数,按我理解就是在声明个变量接收了这个基本类型的值。如果参数是引用类型,则声明的变量指向了这个参数的引用地址,所以修改某个属性,原参数也会跟着变,当把指向改变了,任何操作就对原参数没有影响了。


四、cannot read property of undefined问题解决方案

cannot read property of undefined是很常见的错误,当不知道对象某属性是否存在时,要如何避免报错呢

var user = {
    a: { b: { c: { msg: 'good' } } }
}

1.通过短路运算符进行可访问性嗅探

var user = {
    a: { b: { c: { msg: 'good' } } }
}
console.log( user.a && user.a.b && user.a.b.c &&  user.a.b.c.msg); //good
console.log( user.a && user.a.b && user.a.b.c &&  user.a.b.c.mmm); //undefined

2. 通过||单元设置默认值保底值

var user = {
    a: { b: { c: { msg: 'good' } } }
}
console.log(  ( ( (user.a || {}).b || {} ).c || {} ).msg ); //good
console.log(  ( ( (user.a || {}).b || {} ).c || {} ).mmm ); //undefined

3.使用try...catch

var result
try {
    result =  user.a.b.c.mmm.a
} catch (error) {
    result = null
}
console.log(result); // null

4.简易的get方法

const get = (p, o) => p.reduce( (xs,x)=>(xs&&xs[x]) ? xs[x] : null, o)
console.log(get(['a','b','c','msg'],user)); //good
console.log(get(['a','b','c','mmm'],user)); //null

进行柯里化

const newGet = p => o => p.reduce((xs,x) => (xs&&xs[x]) ? xs[x] : null, o)
const fbn = newGet(['a','b','c','msg'])
console.log(fbn(user));  //good
console.log(fbn( {a:{b:{}}} ));  //null

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值