Javascript之深入浅出prototype
我们先来讲一个故事,一个大大的池塘,里面有很多鱼。这是属于我们大家的池塘所以里面的鱼我们都可以吃,但是我们也会从集市买一些鱼放在家里,那么放在家里的鱼肯定是属于我们私人的,外人是不会拥有的。那么在js里我们就把这个池塘称为原型对象,池塘里面我们所共享的鱼称为原型中的属性及方法,而我们自己的鱼称为构造函数中的属性及方法,我们是什么呢?对了,我们是对象的实例。
以上是为了让大家能够趣味性的对prototype有一个概念,接下来就通过代码具体总结一下prototype~
一、理解prototype
我们创建的每一个函数都有一个prototype属性,这个属性是一个指向对象的指针。
构建对象中有一种模式叫做原型模式,意思是将对象实例所不可共享的属性及方法定义在构造函数中,而将可共享的属性及方法放在原型对象中,也就是prototype指向的对象中。以下是用原型模式创建的一个对象:
1 function person(name, age) { 2 this.name = name; 3 this.age = age; 4 } 5 person.prototype = { 6 sayName: function() { 7 console.log(this.name); 8 } 9 }; 10 11 var p1 = new person("Wind", 20); 12 p1.sayName(); // "Wind" 13 14 var p2 = new person("Nic", 20); 15 p2.sayName(); // Nic
这里我将name、age属性定义在构造函数中,将sayName方法定义在原型中。所以p1和p2对象实例的内存空间里面各有一份name和age,但是它们却共享一份sayName方法,意思是它们调用的sayName方法是同一个。
试想如果我们不用prototype,而是直接将sayName写进构造函数呢?
那么p1和p2中将各有一份sayName,这样浪费内存空间,所以用prototype的好处之一:提高了代码的复用性,减少内存。
在了解原型对象的同时我们还有一个小知识要明白:每当代码读取一个对象属性的时候会执行一次搜索,搜索目标是给定名字的属性,搜索路径为:
对象实例本身---->原型对象---->对象所继承的父类对象---->父类对象原型...---->原型链末端
二、prototype的注意点
1、不可变性:尽管prototype是共享的,但不能通过对象实例重写原型中的值,但是可以由对象统一改。通俗一点:只能爸爸统一改,不能儿子改。(这也和类型有关系,孩子不能改变基本类型的值,但是可以改变对象,比如数组)
基本类型:
1 function person() {} 5 person.prototype = { 6 num: 0 7 }; 8 var p1 = new person(); 9 var p2 = new person(); 10 p1.num++; 11 p2.num; // 0
非基本类型:
1 function person() {} 5 person.prototype = { 6 num: [1,2,3] 7 }; 8 var p1 = new person(); 9 var p2 = new person(); 10 p1.num[2] = 8; 11 p2.num; // [1, 2, 8] 改变了
2、同名覆盖性:如果我们在实例中添加了一个与原型属性同名的属性,那么该属性会创建到对象实例中并且会覆盖掉原型中的相应属性。
1 function person(name) { 2 this.name = name; 3 } 4 person.prototype = { 5 age: 18 6 }; 7 var p1 = new person("Wind"); 8 var p2 = new person("Nic"); 9 p1.age = 20; 10 p1.age; // 20 11 p2.age; // 18
3、使用对象字面量创建原型方法,会切断之前的链而重写原型链
1 function person(name) { 2 this.name = name; 3 } 4 person.prototype = { 5 sayName: function() { 6 console.log(this.name); 7 } 8 }; 9 var p1 = new person("Wind"); 10 11 person.prototype = { 12 age : 20 13 }; 14 p1.sayName(); // Wind 15 p1.age; // undefined 16 17 var p2 = new person("Nic"); 18 p2.sayName(); // error 19 p2.age; // 20
因为prototype指针指向了一个新的对象,切断了构造函数与之前的prototype旧对象的联系,然而p1的prototype指针指向的依旧是旧对象。而新创建的实例p2指向的prototype新对象。
三、总结
prototype的用法:构造函数模型用于定义实例的属性,而原型模型用于定义方法和共享的属性。
mkfs.ext3 option
write file to stroage trigger kernel warning
download fomat install rootfs script
custom usb-seriel udev relus for compatible usb-seriel devices using kermit
Wifi Troughput Test using iperf
learning uboot switch to standby system using button
learning uboot support web http function in qca4531 cpu
learngin uboot design parameter recovery mechanism
learning uboot auto switch to stanbdy system in qca4531 cpu