【亡羊补牢】JS灵魂之问 第18期 修炼内功 Object.creat()基础

引言

有几天没有更新JS灵魂之问的专栏系列文章了,秋招季,也在忙着备战笔试面试。今天得空再来写一篇文章,本篇要讲解的内容是关于 Object.creat()基础 ,那今天这篇看能不能问倒你了,一起来探索一下吧。

仰望星空的人,不应该被嘲笑

Object.creat()基础

之前了解到了 Object,现在我们探讨一下底下的一个方法 create(),它仍然可以创建对象,但是和普通创建对象又不太一样。下面来简单分析一下:

Obeject.create(xxx); // xxx处可以指定自定义原型或者填写null
function Obj(){
    
    
}
Obj.prototype.num = 1;
var obj1 = Object.create(Obj.prototype);
console.log(obj1);

打印出来,此时实例原型的constructor指向这个 Obj()。好的,那我们看看用 new出来的实例对象,有没有什么区别?

function Obj(){
    
    
}
Obj.prototype.num = 1;
var obj1 = Object.create(Obj.prototype);
var obj2 = new Obj();
console.log(obj1);
console.log(obj2);

看看下面结果,发现其实没啥区别,因为都是根据Obj的原型创建出来的。

继续,看看下面这种情况:

var obj1 = Object.create(null);
console.log(obj1);

通过Object.create(null)创建出来的对象,里面啥也没有,这里也就说明了一个点,虽然原型链的顶端是Object.prototype,但是这个特殊的空对象并没有原型,它不会继承于 Object.prototype,因此,不是所有的对象都继承于 Object.prototype

注意,我们没办法自造 __proto__,创建了之后只是相当于属性值一样,实例对象是没有办法调用原型对象上的方法的。

var obj = Object.create(null);
obj.num = 1;
var obj1 = {
    
    
  count: 2
}
obj.__proto__ = obj1;
console.log(obj);
console.log(obj1);

看下面这张图,有咩有发现什么不同,对于我们自造的 __proto__颜色更深有没有?

现在探究一下自己造的 __proto__能不能访问到原型对象上的东西。

var obj = Object.create(null);
obj.num = 1;
var obj1 = {
    
    
  count: 2
}
obj.__proto__ = obj1;
console.log(obj.count);

结果是 undefined,显然没有办法访问,也就证明我们没办法自造 __proto__

好的,上文都是创建了一些对象,下文我们探讨一下特殊例子,比如nullundefined

上文有一个结论,我们发现除开空对象外都能继承Object.prototype,然后访问其中一个方法 toString(),那么nullundefined可以吗?我们测试一下:

console.log(null.toString()); // TypeError: Cannot read property 'toString' of null
console.log(undefined.toString()); // TypeError: Cannot read property 'toString' of undefined

那么,为啥下面这个代码会输出 1呢?

var num = 1;
console.log(num.toString()); // 1

在解释之前,我们再来回顾一下知识点:

原始值是没有属性的,为啥能调用 toString()方法,就是本文目录第三块讲解的包装类的概念了。

它的工作过程如下:

首先 new Number(1),然后再调用toString()方法,因此之前new了一下成为了对象。为了更加准确,我们打印一下看看。

var num = 1;
console.log(num.toString());

var num2 = new Number(num);
console.log(num2);

发现new了之后,在 __proto__里面确实找到了 toString()方法。

回到开头,nullundefined为啥不可以呢?就是因为上文提过nullundefined没办法进行包装。始终为原始值,并且没有原型,也没办法继承。

下面我们探讨一下隐式转换性和继承相关问题,代码如下:

var num = 1;
var obj = {
    
    };
var obj2 = Object.create(null);
document.write(num);
document.write(obj);
document.write(obj2);

然后我们发现最后一个打印有了报错:不能转换为原始值,这是因为啊,obj2创建的空对象没有继承Object.prototype,因此也就没有对应 toString()方法。当然不能转换了。(document.write()方法转换为字符串)

最后

文章产出不易,还望各位小伙伴们支持一波!

往期精选:

小狮子前端の笔记仓库

访问超逸の博客,方便小伙伴阅读玩耍~

学如逆水行舟,不进则退

猜你喜欢

转载自blog.csdn.net/weixin_42429718/article/details/108650077