原型、原型链

一、原型

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属性,有的话就打印出来。


再看一个传参例子。

扫描二维码关注公众号,回复: 1071888 查看本文章
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



猜你喜欢

转载自blog.csdn.net/qq_41713692/article/details/80360558
今日推荐