浅谈Javascript中的对象原型
最近又突然被问起js中的原型,感觉很熟悉,但是实际上又说不出来。今天就抽点事件和大家谈谈js中的原型。
一. 原型是什么?
在js中原型就是构造函数的prototype属性的值,只要是对象就会有prototype的属性。当然这里null是一个特殊的情况。访问原型的方法就是访问对象的prototype,对象的原型prototype也是个对象,所以这个对象也有prototype原型对象.
1 // 原型 2 // 构造函数的prototype属性的值 3 function Person() { 4 this.name = "adfs"; 5 } 6 // 访问原型: 7 console.log(Person.prototype);
二 给原型添加方法
最直接的方法,是可以写在都构造函数的上面,也可以写在原型上面。但是这两种方式有着很大的区别
1 通过对象来调用方法是 通过属性搜索原则找到的方法,然后再调用
2 直接访问到方法,然后再调用的
3 方法内部的 this 指向不同方法内部的this : 谁调用的方法,this就是指向谁
1 // 原型 2 // 构造函数的prototype属性的值 3 function Person() { 4 this.name = "adfs"; 5 } 6 // 访问原型: 7 console.log(Person.prototype); 8 9 // 给原型添加的方法 10 Person.prototype.say = function() { 11 // console.log("这事原型的方法"); 12 console.log(this.name); 13 }; 14 Person.prototype.name = "aaaaaaa"; 15 16 // 表示非公开的方法, 可以使用,但是 可能存在问题 17 // Person.prototype._init = function() {}; 18 19 // 通过构造函数来创建对象 20 var p = new Person(); 21 // 通过p这个实例,来访问到原型中的方法或者是属性 22 p.say(); 23 Person.prototype.say();
三 __proto__访问原型的方式(不推荐使用)
还可以通过通向直接访问到原型 ,只要是带有 __ 就表示非标准的属性, 不能不再实际项目中使用有些框架中写的方法的名字也带有下划线: 表示这些方法是再框架内部使用的 如果,你拿来使用,出问题了,框架不负责
1 p.__proto__ 2 console.log(Person.prototype === p.__proto__); // true
构造函数的prototype属性 和 对象的__proto__表示的就是同一个对象 只不过是 通过不同的方法来访问这个对象(原型)
1 p.__proto__.say(); 2 console.log(p.__proto__);
两个术语(通常我是这么叫的,个人喜好可以,方便区分):
prototype 原型属性
__proto__ 原型对象
就好比是 o1和o2是两个变量,但是这两个变量就是同一个对象
var o1 = {};
var o2 = o1;
四 继承
说到原型就必须要说一下继承。JavaScript继承通俗的话来说,就是拿来主义, 自己没有的,别人有, 把别人的拿过使用或者是变成自己的东西。
1 // 实现继承: prototype 2 3 function Person() {} 4 Person.prototype.say = function() { 5 console.log("hello"); 6 }; 7 8 var p = new Person(); 9 p.say();
在js中最常用的继承的方式有三种:分别是原型继承 、混入继承、经典继承
1 // 混入式继承 2 // 让一个对象继承自 很多其他的对象 3 var o1 = { 4 say: function() { 5 console.log("这是o1中的say方法"); 6 }, 7 num: 1 8 }; 9 10 // 让o2继承自o1 11 var o2 = {}; 12 for(var k in o1) { 13 o2[k] = o1[k]; 14 // o2.k = o1.k; 15 } 16 o2.say(); 17 18 19 // 原型式继承 20 // 21 // 什么叫原型式继承? 如果想让一个对象具有某些属性或方法, 只需要给对象的原型对象来 22 // 添加相关的属性和方法,这样,对象就能够访问到给原型添加的属性或者是方法, 这样就实现了 原型式继承 23 24 function Person() {} 25 26 var o = { 27 constructor: Person, 28 say: function() { 29 console.log("hello world!"); 30 }, 31 coding: function() {}, 32 legs: 2, 33 }; 34 Person.prototype = o; 35 var p = new Person(); 36 37 console.log(p.constructor); // Object函数 38 39 40 // 经典继承: 41 var o = { 42 coding: function() {}, 43 say: function() {} 44 }; 45 46 // 让 obj1 继承自 o 47 // 1 方法会创建一个新对象 48 // 2 新对象会继承自 o 49 var obj1 = Object.create(o); 50 console.log(obj1);
在新的es6中添加了class的概念,那样也可以实现继承。
以上就是我的个人总结关于对象和继承的方式,欢迎大家一起交流。