资讯专栏INFORMATION COLUMN

JavaScript...原型与继承中的原型链...

MiracleWong / 3388人阅读

摘要:原型原型是什么在中函数是一个包含属性和方法的类型的对象而原型就是类型对象的一个属性在函数定义时就包含了属性它的初始值是一个空对象在中并没有定义函数的原型类型所以原型可以是任何类型原型是用于保存对象的共享属性和方法的原型的属性和方法并不会影响

原型 原型是什么

在JavaScript中 函数是一个包含属性和方法的Function类型的对象 而原型(Prototype)就是Function类型对象的一个属性
在函数定义时就包含了prototype属性 它的初始值是一个空对象 在JavaScript中并没有定义函数的原型类型 所以原型可以是任何类型
原型是用于保存对象的共享属性和方法的 原型的属性和方法并不会影响函数本身的属性和方法

// Function类型的属性 -> 所有函数都具有的属性
console.log(Function.prototype);
// 定义函数
function fn(){
    console.log("this is function");
}
// 原型的默认值是空对象
console.log(fn.prototype);
// 函数包含构造函数 -> 所有引用类型其实都是构造函数
console.log(Number.prototype);

console.log(Object.prototype);

var result = Object.getOwnPropertyDescriptor(Object.prototype, "constructor");
console.log(result);
获取原型
function fn(){
    console.log("this is function");
}
// 使用访问对象的属性语法结构
console.log(fn.prototype);
console.log(fn["prototype"]);
// Object类型提供getPrototypeOf()方法
console.log(Object.getPrototypeOf(fn));
为原型新增属性或者方法
function fn(){
    console.log("this is function");
}
// 变量proto也是一个空对象
// var proto = fn.prototype;

// 新增属性或方法
// proto.name = "张三";
fn.prototype.name = "张三";
console.log(fn.prototype);
// defineProperty()
Object.defineProperty(fn.prototype, "age", {
    value : 28,
    enumerable : true
});
console.log(fn.prototype);
构造函数的原型
// 定义构造函数
function Hero(){
    this.name = "张三";
    this.sayMe = function(){
        console.log("this is function");
    }
}
// 操作构造函数Hero的原型
Hero.prototype.age = 28;
// 利用构造函数来创建对象
var hero = new Hero();
console.log(hero);
// 为构造函数的原型新增的属性 -> 构造函数创建的对象中依旧可以访问
console.log(hero.age);// 28
// 对象hero中不存在age属性
var result = Object.getOwnPropertyDescriptor(hero, "age");
console.log(result);
原型属性 自有属性与原型属性

自有属性:通过对象的引用添加的属性 其他对象可能无此属性 即使有 也是彼此独立的属性
原型属性:从原型对象中继承来的属性 一旦原型对象中属性值改变 所有继承该原型的对象属性均改变

// 定义构造函数
function Hero(name){
    // 构造函数本身的属性 -> 自有属性
    this.name = name;
    this.sayMe = function(){
        console.log("this is function");
    }
}
// 通过构造函数Hero的prototype新增属性或方法
// 通过原型所定义的属性 -> 原型属性
Hero.prototype.age = 28;
/*
    通过构造函数Hero创建对象时
    * 不仅具有构造函数的自有属性
    * 还具有构造函数的原型属性
 */
var hero = new Hero("张三");

console.log(hero.name);// 张三
console.log(hero.age);// 18

var hero2 = new Hero("李四");
console.log(hero2.name);// 李四
console.log(hero2.age);// 28
// 为对象hero新增age属性
// hero.age = 80;
// console.log(hero.age);// 80
//
// console.log(hero);
//
// console.log(hero2.age);// 28

Hero.prototype.age = 80;

console.log(hero.age);
console.log(hero2.age);
重写属性

通过构造函数或对象的自有属性可以重写原型的属性

// 定义构造函数
function Hero(){
    this.name = "张三";
}
// 构造函数的原型
Hero.prototype.name = "李四";
// 构造函数创建对象
var hero = new Hero();
// 自有属性与原型属性同名时,默认访问的是自有属性 -> 自有属性的优先级别高于原型属性
console.log(hero.name);// 张三

// 删除对象的属性
delete hero.name;
// 重新访问对象的属性
console.log(hero.name);// 李四
检测原型属性
function Hero(){
//this.name = "张三";// 自有属性
}
 //Hero.prototype.name = "李四";

var hero = new Hero();
/*
    Object.hasOwnProperty(prop)方法
    * 作用 - 判断当前指定属性是否为自有属性
    * 参数
      * prop - 表示指定属性名称
    * 返回值 - 布尔值
      * true - 表示存在指定的自有属性
      * false - 表示不存在指定的自有属性
 */
// console.log(hero.hasOwnProperty("name"));// true
/*
    使用in关键字检测对象的属性
    * 作用 - 判断对象中是否存在指定属性(自有属性或原型属性)
    * 返回值 - 布尔值
      * true - 表示存在指定的属性
      * false - 表示不存在指定的属性
 */
console.log("name" in hero);
操作原型的方式
// 定义构造函数
function Hero(){}
// 通过构造函数的原型新增属性或方法

// 1.利用对象.属性或方法的方式新增属性或方法
Hero.prototype.name = "张三";
Hero.prototype.sayMe = function(){
    console.log("this is function");
}
// 2.将原型重新赋值为一个新对象
Hero.prototype = {
    name : "张三",
    sayMe : function(){
        console.log("this is function");
    }
}

// 通过构造函数创建对象
var hero = new Hero();

console.log(hero.name);
hero.sayMe();
显式原型与隐式原型
// 定义构造函数
function Hero(){
    this.name = "张三";
}
// 通过构造函数的原型新增属性或方法
Hero.prototype.age = 28;
// 通过构造函数创建对象
var hero = new Hero();

console.log(hero.name);// 对象调用自有属性
console.log(hero.age);// 对象调用原型属性

/*
    所有对象其实也具有原型
    * 注意 - 对象的原型(__proto__)并非是函数的原型(prototype)
    * 区分
      * 将函数的原型 -> 显式原型
      * 将对象的原型 -> 隐式原型
    * 对象的原型
      * 不能用于真实开发工作,仅用于逻辑测试
 */
console.log(hero.prototype);// undefined 表示对象中不存在该属性
console.log(hero.__proto__);
isPrototypeOf()方法

每个对象中都会具有一个isPrototypeOf()方法 该方法用来判断一个对象是否是另一个对象的原型

// 通过初始化器方式定义对象
var obj = {
    name : "张三"
}
//定义构造函数
function Hero(){}
//将对象obj赋值给构造函数Hero的原型
Hero.prototype = obj;
//通过构造函数创建对象
var hero = new Hero();
//判断指定对象是否是另一个对象的原型
var result = obj.isPrototypeOf(hero);

console.log(result);
扩展内置对象

JavaScript中的内置对象有些也具有prototype属性 利用内置对象的prototype属性可以为内置对象扩展属性或方法
通过原型扩展内置对象的属性和方法非常灵活 根据个性化要求制定Java Script语言的具体内容

Object.prototype.sayMe = function(){
    console.log("this is sayMe function");
}
// 通过Object构造函数创建对象
var obj = new Object();

obj.sayMe();


Array.prototype.inArray = function(color){
    // this - 表示当前的数组
    for(var i = 0, len = this.length; i < len; i++){
        if(this[i] === color){
            return true;
        }
    }
    return false;
}
var arr = ["red", "green", "blue"];

console.log(arr.inArray("red")); //true
console.log(arr.inArray("yellow")); //false
继承 原型链是什么

构造函数或构造器具有prototype属性 对象具有__proto__属性 这就是之前学习的原型
如果构造函数或对象A A的原型指向构造函数或对象B B的原型在指向构造函数或对象C 以此类推 最终的构造函数或对象的原型指向Object的原型 由此形成一条链状结构 被称之为原型链
按照上述的描述 在B中定义的属性或方法 可以直接在A中使用并不需要定义 这就是继承 它允许每个对象来访问其原型链上的任何属性或方法

// 原型链
function A(){
    this.a = "a";
}
// 通过构造函数创建对象
var a = new A();

function B(){
    this.b = "b";
}
// 将B的原型指向对象a
B.prototype = a;
// 通过构造函数创建对象
var b = new B();

console.log(b.b);// b
console.log(b.a);// a

function C(){
    this.c = "c";
}
// 将C的原型指向对象b
C.prototype = b;
// 通过构造函数创建对象
var c = new C();

console.log(c.c);// c
console.log(c.b);// b
console.log(c.a);// a
只继承于原型

处于对效率的考虑 尽可能地将属性和方法添加到原型上
1.不要为继承关系多带带创建新对象
2.尽量减少运行时的方法搜索

// 原型链
function A(){
    // 将自有属性改写为原型属性
    // this.a = "a";
}
A.prototype.a = "a";

function B(){
    // this.b = "b";
}

// 将B的原型指向
B.prototype = A.prototype;

B.prototype.b = "b";
/*B.prototype = {
    b : "b"
}*/

function C(){
    this.c = "c";
}
// 将C的原型指向
C.prototype = B.prototype;

var c = new C();
console.log(c.c);// c
console.log(c.b);
console.log(c.a);// a
原型链实现继承的问题
// 原型链
function A(){
    // 将自有属性改写为原型属性
    // this.a = "a";
}
A.prototype.a = "a";

function B(){
    // this.b = "b";
}

// 将B的原型指向
B.prototype = A.prototype;

B.prototype.b = "b";

function C(){
    // this.c = "c";
}
// 将C的原型指向
C.prototype = B.prototype;
C.prototype.c = "c";

var c = new C();
console.log(c.c);// c
console.log(c.b);// b
console.log(c.a);// a

var a = new A();

console.log(a.a);
console.log(a.b);
console.log(a.c);

var b = new B();

console.log(b.a);
console.log(b.b);
console.log(b.c);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108285.html

相关文章

  • JavaScript系列--浅析原型继承

    摘要:综上所述有原型链继承,构造函数继承经典继承,组合继承,寄生继承,寄生组合继承五种方法,寄生组合式继承,集寄生式继承和组合继承的优点于一身是实现基于类型继承的最有效方法。 一、前言 继承是面向对象(OOP)语言中的一个最为人津津乐道的概念。许多面对对象(OOP)语言都支持两种继承方式::接口继承 和 实现继承 。 接口继承只继承方法签名,而实现继承则继承实际的方法。由于js中方法没有签名...

    draveness 评论0 收藏0
  • 彻底理解Javascript中的原型继承

    摘要:在节中,我们学习到了通过构造函数创建对象的三个重要步骤,其中的一步是把构造函数的对象设置为创建对象的原型。利用而不是直接用创建一个实例对象的目的是,减少一次调用父构造函数的执行。 JavaScript语言不像面向对象的编程语言中有类的概念,所以也就没有类之间直接的继承,JavaScript中只有对象,使用函数模拟类,基于对象之间的原型链来实现继承关系,ES6的语法中新增了class关键...

    ziwenxie 评论0 收藏0
  • 你是否理解js的ObjectFunction原型

    摘要:原型对象是由创建的,因此原型对象的构造函数是构造函数也可以是称为对象,原型对象也就继承了其生父构造函数中的数据,也同时继承了原型对象的数据。当然这条原型链中的数据,会被还是还是这类构造函数继承,但是不会被这些继承,他们不处于同一个链条上。 js中,Function的本质是什么?Object的本质又是什么?js中有几条原型链? showImg(https://segmentfault.c...

    itvincent 评论0 收藏0
  • javaScript原型原型详解(二)

    摘要:当然这还没完,因为我们还有重要的一步没完成,没错就是上面的第行代码,如果没有这行代码实例中的指针是指向构造函数的,这样显然是不对的,因为正常情况下应该指向它的构造函数,因此我们需要手动更改使重新指向对象。 第一节内容:javaScript原型及原型链详解(二) 第一节中我们介绍了javascript中的原型和原型链,这一节我们来讲利用原型和原型链我们可以做些什么。 普通对象的继承 ...

    widuu 评论0 收藏0
  • 进击JavaScript之(四)原型原型

    摘要:每一个由构造函数创建的对象都会默认的连接到该神秘对象上。在构造方法中也具有类似的功能,因此也称其为类实例与对象实例一般是指某一个构造函数创建出来的对象,我们称为构造函数的实例实例就是对象。表示该原型是与什么构造函数联系起来的。 本文您将看到以下内容: 传统构造函数的问题 一些相关概念 认识原型 构造、原型、实例三角结构图 对象的原型链 函数的构造函数Function 一句话说明什么...

    XBaron 评论0 收藏0
  • 原型原型理解

    原型与原型链理解 1. 什么是原型 JavaScript是一种简易的脚本语言,其是由对象构成。每一个JavaScript对象(除null外)都和另一个对象相关联,另一个对象就是原型。也就是说,任何一个对象都有原型这个属性。 隐式原型(_proto_):上面说的这个原型是JavaScript中的内置属性[[prototype]],此属性继承自object对象,在脚本中没有标准的方式访问[[pro...

    YJNldm 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<