我对js中原生对象和原型对象的理解
在之前我总结了定义对象的方法,现在看了本章对对象的深入介绍,我再总结一下我目前所理解的对象和之前对对象的认识在理解上存在的差异。先看一下以前经常写的两个创建实例的函数写法:
function Person(name, age) { this.name = name; this.age = age; this.sayName = () => { alert(this.name); } } var person1 = new Person("zhang", 20); var person2 = new Person("li", 30);
以上这种写法,是我以前一直习惯用的一个写法,这种写法貌似看着不错,简单易懂。今天看了这部分的介绍,才明白这种写法的缺点。首先,就是我在上面创建了两个实例,而每个构造函数中都含有一个变量式声明的函数,这就需要在进行实例化的时候重新new Function()了。缺点来了!那就是重新开辟了内存空间,占用内存!
这还不算完,它会引发每个实例的sayName()函数不一样,但是每个sayName()函数又会执行相同的功能,这就有点冗余了。
console.log(person1.name === person2.name); // false
所以,下面的这种写法就是为了解决不同实例中创建方法不一样的问题,感谢很有意思,所以把它写下来了。
function Person(name, age) { this.name = name; this.age = age; this.sayName = sayName; } // 创建了一个全局函数 function sayName() { alert(this.name); } var person1 = new Person("zhang", 20); var person2 = new Person("li", 30);
这就是解决方法,确实是解决了两个实例中的函数做同一件事情的问题。我在这里的理解是,它功能局限,只能本一个对象调用,没有全局的意思了啊。而且如果有多个不同的对象去调用不同的函数,那就需要在外面创建多个全局函数。
接下来就是使用原型模式进行解决的方案,当然今天我只是看到了这里,后边的小节中应该还会有其它方案,我这里暂时做个小结。
function Person() { } // 通过原型模式进行对属性操作 Person.prototype.name = "lisi"; Person.prototype.age = 26; Person.prototype.sayName = function() { alert(this.name); }; var person1 = new Person(); var person2 = new Person();
通过👇这张图我的第一感觉就是两个实例公用了构造函数的属性和方法,那就是节省内存,因为实例中的内部属相都会指向原型对象,恰好这里面有属相和方法,可以公用。但是从图中可以看到,实例和构造函数之间没有直接关系,而且构造函数的原型对象的构造函数属相(constructor属性)是指向构造函数的,这里我在以前的继承中使用过这种写法,只是当时不太了解中间的连接和关系。
并且可以通过两个方法进行验证实例的原型对象和构造函数的原型对象之间的关系。分别为,isPrototypeOf()和getPrototypeOf(),里面的参数都是实例对象
// 方法1,之前使用的是这一种进行验证的 console.log(Person.prototype.isPrototypeOf(person1)); // true console.log(Person.prototype.isPrototypeOf(person2)); // true // 方法2,是基于Object对象进行调用的 console.log(Object.getPrototypeOf(person1) === Person.prototype); // true console.log(Object.getPrototypeOf(person2) === Person.prototype); // true
下面👇这是这是一张简介的原型图链接:
今天看了一部分,相信后面的小结应该就是精华了。但是要想了解的更清楚还是看看原创或者更详细的文章,因为看博客或者别人写的东西,只是片面了解,因为知识在传播的过程中的信息量会逐渐减少的!这中间可能就有一些打通你思路的东西。
网友评论