资讯专栏INFORMATION COLUMN

JavaScript面向对象中的原型个人分享

pakolagij / 2916人阅读

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

原型 原型是什么

所谓原型(Prototype)就是Function类型对象的一个属性

在函数定义时就包含了prototype属性,它的初始值是以个空对象.在JavaScript中并没有定义函数的原型类型,所以原型可以是任何类型

原型是用于保存对象的共享属性和方法的,原型的属性和方法并不会影响函数本身的属性和方法

示例代码:

// Function类型的属性 - 就是所有函数都具有的属性
console.log(Function.prototype);
// 定义函数
function fn() {
    console.log("一花一世界");// 调用结果为 [Function]
}
// 原型的默认值是空对象
console.log(fn.prototype);// 调用结果为 fn {}


// 函数包含构造函数 - 就是所有引用类型其实都是构造函数
console.log(Number.prototype);// 调用结果为 [Number: 0]

console.log(Object.prototype);// 调用结果为 {}

var result = Object.getOwnPropertyDescriptor(Object.prototype,"constructor");
console.log(result);
获取原型

可以通过两种方式获取原型,从而设置共享的属性和方法

1. 通过构造函数的prototype属性

示例代码:

function fn() {
    console.log("一花一世界");
}
// 使用访问对象的属性语法结构
console.log(fn.prototype);// 调用结果为 fn {}
console.log(fn["prototype"]);// 调用结果为 fn {}
2. 通过Object对象的getPrototypeOf()方法

示例代码:

// Object类型提供getPrototypeOf()方法
function fn() {
    console.log("一花一世界");
    
console.log(Object.getPrototypeOf(fn));// 调用结果为 [Function]
为原型新增属性或方法

示例代码:

function fn() {
    console.log("一花一世界");
}
// 变量proto也是一个空对象
//var proto = fn.prototype;
//console.log(proto);// 调用结果为 fn {}

//新增属性或方法
// 1. prototype.name = "小燕子";
fn.prototype.name = "小燕子";
console.log(fn.prototype);// 调用结果为 fn { name: "小燕子" }

// 2. defineProperty() - 表示定义属性
Object.defineProperty(fn.prototype,"age",{
    value : 21 + "岁",
    /* 可枚举 */
    enumerable : true
});
console.log(fn.prototype);// 调用结果为 fn { name: "小燕子", age: "21岁" }
构造函数的原型

示例代码:

// 定义构造函数
function Hero() {
    this.name = "一花一世界";
    this.sayMe = function () {
        console.log("花花世界");
    }
}
// 操作构造函数Hero的原型
Hero.prototype.age = 26;
// 利用构造函数来创建对象
var hero = new Hero();
console.log(hero);// 调用结果为 Hero { name: "一花一世界", sayMe: [Function] }
// 为构造函数的原型新增的属性 - 构造函数创建的对象中依旧可以访问
console.log(hero.age);// 调用结果为 26
// 对象hero中不存在age属性
// getOwnPropertyDescriptor - 表示获取私有属性描述符
var result = Object.getOwnPropertyDescriptor(hero,"age");
console.log(result);// 调用结果为 undefined

代码分析图:

自有属性与原型属性

自有属性 - 通过对象的引用添加的属性.其它对象可能无此属性;即使有,也是彼此独立的属性

原型属性 - 从原型对象中继承来的属性,一旦原型对象中属性值改变,所有继承自该原型的对象属性性均改变

示例代码:

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

console.log(hero.name);//调用结果为 花花世界
console.log(hero.age);//调用结果为 26

var hero2 = new Hero("一笑一人生");
console.log(hero2.name);//调用结果为 一笑一人生
console.log(hero2.age);//调用结果为 26

// 为对象hero新增age属性
hero.age = 62;
console.log(hero.age);// 调用结果为 62

console.log(hero);// 调用结果为 Hero { name: "花花世界", sayMe: [Function], age: 62 }
console.log(hero2.age);//调用结果为 26

Hero.prototype.age = 77;

console.log(hero.age);// 调用结果为 62
console.log(hero2.age);// 调用结果为 77
重写属性

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

示例代码:

// 定义构造函数
function Hero() {
    this.name = "花花世界";
}

// 构造函数的原型
Hero.prototype.name = "醉影笑惊鸿";
// 构造函数创建对象
var hero = new Hero();

// 自有属性与原型属性同名时,默认访问的是自有属性 - 自有属性的优先级别高于原型属性
console.log(hero.name);// 调用结果为 花花世界

// 删除对象的属性 - 删除的是自有属性要,因为自有属性的优先级别高于原型属性所以需要先删除自有属性才能调用到原型属性(前提是自有属性和原型属性要同名的情况)
delete hero.name;
// 重新访问对象的属性
console.log(hero.name);// 调用结果为 醉影笑惊鸿

控制台效果对比图:

检测原型属性

Object.hasOwnProperty(prop)方法

作用 - 判断当前指定属性是否为自有属性

参数 - prop - 表示指定属性名称

返回值 - 布尔值

true - 表示存在指定的自有属性

false - 表示不存在指定的自有属性

使用in关键字检测对象的属性

作用 - 判断对象中是否存在指定属性(自有属性或原型属性)

返回值 - 布尔值

true - 表示存在指定的属性

false - 表示不存在指定的属性

示例代码:

function Hero() {
    //this.name = "醉影笑惊鸿"// 自有属性
}

//Hero.prototype.name = "花花世界";

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

控制台效果对比图:

操作原型的方式 1. 利用对象.属性或方法的方式新增属性或方法

示例代码:

// 定义构造函数
function Hero() {}
// 通过构造函数的原型新增属性或方法

Hero.prototype.name = "一花一世界";
Hero.prototype.sayMe = function () {
    console.log("醉影笑惊鸿");
// 通过构造函数创建对象
var hero = new Hero();

console.log(hero.name);//调用结果为 一花一世界
hero.sayMe();//调用结果为 醉影笑惊鸿
2. 将原型重新赋值为一个新对象

示例代码:

// 定义构造函数
function Hero() {}
// 通过构造函数的原型新增属性或方法

Hero.prototype = {
    name : "一笑一人生",
    sayMe : function () {
        console.log("极乐世界");
    }
};

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

console.log(hero.name);//调用结果为 一笑一人生
hero.sayMe();//调用结果为 极乐世界
显示原型与隐式原型

所有对象其实也具有原型

注意 - 对象的原型(__proto__)并非是函数的原型(prototype)

区分:

将函数的原型 -> 显式原型

将对象的原型 -> 隐式原型

对象的原型

不能用于真实开发工作,仅用于逻辑测试

注意: __proto__属性只能在调用时使用. __proto__属性与prototype属性并不等价.

示例代码:

// 定义构造函数
function Hero() {
    this.name = "皮卡丘";
}

// 通过构造函数的原型新增属性或方法
Hero.prototype.age = 26;
// 通过构造函数创建对象
var hero = new Hero();

console.log(hero.name);// 对象调用自有属性 结果为 皮卡丘
console.log(hero.age);// 对象调用原型属性 结果为 26

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

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

示例代码:

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

console.log(result);// 调用结果为 true - 表示是另一个对象的原型
扩展内置对象

通过原型扩展内置对象的属性和方法非常灵活, 根据个性化要求定制JavaScript语言的具体内容

注意: 一般不建议使用这种方式,如果JavaScript的版本更新时可能会提供个性化的属性或方法,会导致冲突

示例代码:

Object.prototype.sayMe = function(){
    console.log("一花一世界");
}
// 通过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
扩展内置对象补充

示例代码:

/* 定义对象原型属性 */
Object.defineProperty(Object.prototype, "sayMe", {
    /* 函数方法 */
    value : function(){
        /* 函数体 */
        console.log("一花一世界");
    }
});
/* 定义变量并赋值新创建的对象 */
var obj = new Object();
/* 调用创建的函数属性 */
obj.sayMe();// 调用结果为 一花一世界

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

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

相关文章

  • JavaScript面向对象中的继承个人分享

    摘要:继承原型链所谓言行链就是如果构造函数或对象的原型指向构造函数或对象的原型再指向构造函数或对象以此类推最终的构造函数或对象的原乡指向的原型由此形成一条链状结构被称之为原型链示例代码原型链通过构造函数创建对象将的原型指向对象通过构造函数创建对象 继承 原型链 所谓言行链就是如果构造函数或对象A,A的原型指向构造函数或对象B,B的原型再指向构造函数或对象C,以此类推,最终的构造函数或对象的原...

    Coly 评论0 收藏0
  • JavaScript面向对象中的严格模式个人分享

    摘要:严格模式严格模式的概念所谓严格模式就是对中的一种限制性更强的方式属于代码的一种强制规则来规范代码的格式简单的说就是必须按照严格模式的规则书写代码否则就会报错严格模式修正了一些引擎难以优化的错误同样的代码有些时候严格模式会比非严格模式下更加快 严格模式 严格模式的概念 所谓严格模式就是对JavaScript中的一种限制性更强的方式. 属于代码的一种强制规则,来规范代码的格式简单的说就是...

    lordharrd 评论0 收藏0
  • 【重温基础】15.JS对象介绍

    摘要:构造函数通常首字母大写,用于区分普通函数。这种关系常被称为原型链,它解释了为何一个对象会拥有定义在其他对象中的属性和方法。中所有的对象,都有一个属性,指向实例对象的构造函数原型由于是个非标准属性,因此只有和两个浏览器支持,标准方法是。 从这篇文章开始,复习 MDN 中级教程 的内容了,在初级教程中,我和大家分享了一些比较简单基础的知识点,并放在我的 【Cute-JavaScript】系...

    booster 评论0 收藏0
  • JS对象(1)重新认识面向对象

    摘要:对象重新认识面向对象面向对象从设计模式上看,对象是计算机抽象现实世界的一种方式。除了字面式声明方式之外,允许通过构造器创建对象。每个构造器实际上是一个函数对象该函数对象含有一个属性用于实现基于原型的继承和共享属性。 title: JS对象(1)重新认识面向对象 date: 2016-10-05 tags: JavaScript 0x00 面向对象 从设计模式上看,对象是...

    superw 评论0 收藏0
  • JavaScript面向对象中的Array类型个人分享

    摘要:类型检测数组示例代码调用结果为方法作用用于判断当前对象的数据类型结果特点可以准确判断出当前变量的类型调用结果为调用结果为报错调用结果为调用结果为方法判断指定类型是否出现在当前对象的原型链中调用结果为转换数组提供了两种方法用于数组的转 Array类型 检测数组 示例代码: var arr = [1,2,3,4,5]; console.log(arr instanceof Array);/...

    KnewOne 评论0 收藏0

发表评论

0条评论

pakolagij

|高级讲师

TA的文章

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