ES6中继承的基本使用
<script>
// ES6中继承的基本使用
class A{ //constructor 构造器,构造函数
constructor(a) {
this.a = a; // 私有属性
}
getA(){ // 公有属性
console.log("-–>",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>
结论:
- typeof只能检测基本数据类型和函数,对于引用数据类型是检测不了的
- 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
缺点:
- 只能检测引用数据类型 检测基本数据类型不给力
- 所有的引用数据类型都是Object的实例,只要在当前对象的原型链上出现的类,检测的结果一直是true
- 可以人为修改它的原型链 检测数据类型就不靠谱
<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
缺点:
- 不能检测基本数据类型
- 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>