20-05-ES6继承、instanceof、检测数据类型typeof instanceof constructor toString

ES6中继承的基本使用

<script>
    // ES6中继承的基本使用
    class A{	//constructor 构造器,构造函数
        constructor(a) {
            this.a = a;  // 私有属性
        }
        getA(){    // 公有属性
            console.log("-&ndash;&gt;",this.a)
        }
    }
    class B extends A{   // ES6中继承
       constructor(n) {
           super(n); // 调用父类的constructor
       }
    }
    let obj = new B("666"); // new B时,肯定要执行constructor
    console.log(obj.a);  //666
    obj.getA();			//ange 666
</script>

instanceof

实例 运算符 判断对象类型
判断某个对象是否是某个类的实例
判断前面构造的函数是否是后面函数的实例
只能检测引用数据类型,不能检测基本数据类型

console.log(obj instanceof B);			true
console.log(obj instanceof Array);		false
console.log(obj instanceof A); 			true

模拟instanceof

instanceof是运算符,只能用函数模拟

<script>
    function myinstaceof(m, N) {
        N = N.prototype;	//N的原型对象
        m = m.__proto__;	//实例的也是原型对象
        while (true) {
            if (m === null) {
                return false;
            }
            if (m === N) {
                return true
            }
            m = m.__proto__;
        }
    }
    class A {
        constructor(a) {
            this.a = a;
        }
        getA() {
            console.log("--->", this.a)
        }
    }
    class B extends A {
        constructor(n) {
            super(n);
        }
    }
    let obj = new B("666");
    console.log(myinstaceof(obj, B))
    console.log(myinstaceof(obj, Array))
    console.log(myinstaceof(obj, A))
</script>

检测数据类型

typeof

typeof 是运算符 单目运算符 可以判断JS中一个数据的数据类型 返回值是一个字符串。
typeof对于基本数据类型判断是没有问题的,但是遇到引用数据类型(如:Array)是不起作用的。

<script>
    // typeof是运算符  即使你加了()
    console.log(typeof(123)); // number
    console.log(typeof typeof 123); // number
    console.log(typeof "hello"); // string
    console.log(typeof undefined); // undefined
    console.log(typeof null); // object
    console.log(typeof function () { }); // function
    console.log(typeof {}); // object
    console.log(typeof ["1"]); // object
    console.log(typeof NaN); // number
</script>

结论:

  1. typeof只能检测基本数据类型和函数,对于引用数据类型是检测不了的
  2. typeof返回值都是字符串类型,有如下几个:“number”,
    “string”,“boolean”,“function”,“undefined”,“object”,“symbol”

优点:简单
缺点:对引用数据类型检测不准确

typeof 应用

给形参赋默认值的方案

<script>
    function fn(num) {
		if(num==undefined) num = 666;  // 判断num的值是否是undefeind
        num = num || 666;  // 经典,num有值就有,没值就赋值666
  		if(typeof num=="undefined") num = 666;  // 判断num的类型是否是undefined
    	typeof num == "undefined" ? num = 666 : null;   // 经典
    }
    fn()
</script>

判断形参的值

<script>
    function gn(callback) {
        // 判断形参的值
        // if(callback) callback();
        callback && callback(); // 经典
        // 判断形参的类型
        // typeof callback === "function" ? callback() : null;  // 经典代码
    }
    gn();
    gn(function () {
        console.log("xxxx")
    })
</script>

instanceof

运算符 返回true或false

缺点:

  1. 只能检测引用数据类型 检测基本数据类型不给力
  2. 所有的引用数据类型都是Object的实例,只要在当前对象的原型链上出现的类,检测的结果一直是true
  3. 可以人为修改它的原型链 检测数据类型就不靠谱
<script>
    let a = 1;
    let b = "hello";
    console.log(a instanceof Number);  // false
    console.log(b instanceof String);  // false

    console.log({} instanceof Object); // ==> true
    console.log([] instanceof Array);  // ==> true
    console.log(function () { } instanceof Function);  // ==> true

    console.log([] instanceof Object);  // ==> true
    console.log(function () { } instanceof Object);  // ==> true
</script>

constructor

缺点:

  1. 不能检测基本数据类型
  2. constructor指向非常容易修改
<script>

    let n = new Number(110); // n是一个对象
    n.constructor = Array; // 手动修改了constructor的指向
    console.log(n.constructor === Number); // ==> true
    console.log({}.constructor === Object); // ==> true
    console.log({}.constructor === Number); // ==> false
    console.log([].constructor === Array); // ==> true

    // console.log(123.constructor === Number); // ==> 报错
    // console.log("hello".length)
</script>

toString

Object.prototype.toString.call()
这个是最好的解决方案

<script>
    // Object 类  Object.prototype.toString
    // console.log(123.toString());  // 这样写不行
    console.log(Object.prototype.toString.call(123)); //  [object Number]
    console.log(typeof Object.prototype.toString.call(123)); //  string
    console.log(Object.prototype.toString.call("hello")); //  [object String]
    console.log(Object.prototype.toString.call(true)); //  [object Boolean]
    console.log(Object.prototype.toString.call([])); //  [object Array]
    console.log(Object.prototype.toString.call({})); //  [object Object]
    console.log(Object.prototype.toString.call(function () { })); //  [object Function]
    console.log(Object.prototype.toString.call(/abc/)); //  [object RegExp]

    console.log({}.toString.call(666)); // [object Number]
</script>

封装方法

<script>
var class2type = {};
var toString = class2type.toString; //=>Object.prototype.toString
var hasOwn = class2type.hasOwnProperty; //=>Object.prototype.hasOwnProperty
var fnToString = hasOwn.toString; //=>Function.prototype.toString
var ObjectFunctionString = fnToString.call(Object); //=>Object.toString() =>"function Object() { [native code] }"

"Boolean Number String Function Array Date RegExp Object Error Symbol".split(" ").forEach(function anonymous(item) {
    class2type["[object " + item + "]"] = item.toLowerCase();
});
console.log(class2type);
/* [object Boolean]: "boolean"
[object Number]: "number"
[object String]: "string"
[object Function]: "function"
[object Array]: "array"
[object Date]: "date"
[object RegExp]: "regexp"
[object Object]: "object"
[object Error]: "error"
[object Symbol]: "symbol"
*/

function toType(obj) {
    //=>obj may be null / undefined
    //=>return "null"/"undefined"
    if (obj == null) {
        return obj + "";
    }

    return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj;
}
console.log(toType({})); //object
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值