原型、原型链
一、原型
1、定义:原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。
2、利用原型特点和概念,可以提取公有属性。
3、对象如何查看原型 ———>隐式属性__proto__
4、对象如何查看对象的构造函数 ——>constructor 俗称构造器
下面依次举例解释一下:
1、原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法
例如先写一个Person的构造函数:
function Person(){
console.log("hehe");
}
那么Person 函数的原型是 Person.protope
因为原型也是对象,那么Person.protope = {} 就表示Person函数的祖先。
原型也可以传参,
看个具体例子吧。
Person.prototype.name = "我是Person的一个属性";
function Person(){
}
var person = new Person();
此时Person函数里面没有定义,但是当我们访问person.name 的时候出现
那我们就可以发现是可以打印出来的。因为原型里面定义了name属性,当我们要访问的时候Person函数自己没有定义,它就从原型里面找name属性,有的话就打印出来。
再看一个传参例子。
Person.prototype.LastName = "Deng";
Person.prototype.say = function(){
console.log("hehe");
}
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
var person = new Person('happy',18,'gril');
我们来看一下结果:
2、利用原型特点和概念,可以提取公有属性
利用原型对象解决代码的冗余(代码的耦合):提取公有属性。
还是举例说明:
Car.prototype ={
carName : "BMN",
height : 1400,
lang : 4900,
}
function Car(color , owner){
this.color = color;
this.owner = owner;
}
var car1 = new Car('red','张三');
var car2 = new Car('green', '张二');
var car3 = new Car('yellow', '张一');
原型的增删改查:不可能通过后代(对象)来改变原型,除非用Person.prototype.LastName = '123';类似的语句进行修改
3、对象如何查看原型 -——>隐式属性 __proto__
举个例子吧~
Person.prototype.name = 'abc';
function Person(){
}
var person = new Person();
如果我们访问person.name那么执行过程是这样的:
先在自己对象里面找name,如果找不到就沿着__proto__找原型,在原型里面找。
var this = {
__proto__ : person.prototype,
}
所以输出结果为‘abc’。
练习两个问题:
(1)
Person.prototype.name = 'sunny';
function Person(){
}
var person = new Person();
Person.prototype = {
name : 'cherry'
}
--> person.name 结果: sunny
(2)
Person.prototype.name = 'sunny';
function Person(){
}
Person.prototype = {
name : 'cherry'
}
var person = new Person();
----> person.name 结果:cherry 【预编译过程】
4、对象如何查看对象的构造函数———>constructor 俗称构造器
function Person(){
}
var person = new Person();
Car.prototype = {
constructor : Person,
}
function Car(){
}
var car = new Car();
二、原型链
原型链的增删改查,与原型相似,就近原则。
只有本人具有增删改查的权限,不能通过子孙进行操作
Object.create(原型) ——————>也可以构造对象
我们可以看几道题来试一下:
Grand.prototype.__proto__ = Object.prototype;
Grand.prototype.lastName = 'Deng';
function Grand(){
}
var grand = new Grand();
Father.prototype = Grand;
function Father(){
this.name = 'xuming';
this.fortune = {
card1 : 'visa',
}
this.num = 100;
}
var father = new Father();
Son.prototype = father;
function Son(){
this.hobbit = 'smoke';
this.num ++;
}
var son = new Son();
// -----console.log(Father.num); 结果为 100
// -----console.log(son.sum); 结果为101
此题中son不能修改father中的属性,但是father可以自己修改自己的属性;与此同理,father不能修改grand中的属性,但grand可以自行修改自己的属性。也就是说子级不能修改父级中的属性,只能通过自身修改。
再来看一道题目
Person.prototype = {
name : "a",
sayName : function(){
console.log(this.name);
}
}
function Person (){
this.name = 'b';
}
var person = new Person();
想一下会打印什么?【提示:sayName里面的this指向是,谁调用这个方法,this就指向谁】
结果打印b
object.create(原型) 也可用来构造对象。
var obj = Object.create(原型);
举个例子吧。
var obj = {
name : "sunny",
age : 123,
}
var obj1 = Object.create(obj);
那么obj1 的原型就是obj 。
注意喽:绝大多数对象最终都会继承自Object.prototype
因为有Object.create(原型)来构造原型对象,所以是绝大多数,下面解释一下:
Object.create()里面只能放原型,那如果我们在括号里面什么都不放呢?
那么就会出现错误提示,对象原型只能是一个对象或null
那么我们再来试一下null的情况
我们看到里面并没有原型,那么我们可以自己可以给对象添加上原型吗?
var obj = Object.create(null);
我们人为给加上的原型不能用,所以说原型是系统内部的隐式属性,只能是系统给了,我们自己添不能用。
所以说全部对象最终都会继承自Object.prototype是错误的!
还有一种情况,当我们在里面加上原始值,结果会怎样?
则会报错!所以原始值是不行滴。
toString
现在来说一下toString。回顾一下 undefined和null两个不能用toString 现在来解释一下为什么不能。
因为undefined 和null 不是对象,没有包装的类,所以没有原型,没有原型是不能调用toString方法的!
没有原型不能调用toString方法 【null 和 undefined】
一般调用终端object.toString (),但是有的对象原型上面就有toString方法,这时候自己重写一个toString方法就可以。
首先 123.toString();会出错,因为在数字里面那个调用的点表示浮点型,优先级最高。一般写成:
var num = 123;
num.toString(); // ------> new Number(num).toString();
Number.prototype.toString = function(){ //方法的重写,名字相同,功能不同
}
因为Number原型上面有toSting方法,所以就不用调用Object上面的toSting方法了。自己重写一个方法就可以。
// Object.prototype.toString
// Number.prototype.toString
// Array.prototype.toString
// Boolean.prototype.toString
// String.prototype.toString
这些数据类型上面都有toString方法。
下面看一个小例子吧。
Number.prototype.toString = function(){
return "hehe"
}
var num = 123;
console.log(num.toString());
输出 :hehe上一篇: PHP识别用户上传的色情图片并防止实例
下一篇: 图书馆剔旧