这样理解原型,更加容易易懂

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。所有原型对象都会自动获得一个consturctor属性,这个属性指向prototype属性所在函数的指针。Person.prototype.constructor 指向Person。通过这个构造函数可以继续为原型对象添加其他属性和方法.

1.prototype:

只要我们定义一个函数,prototype作为函数的属性存在了,它的初始值是一个对象。

function Person () {

}
Person.prototype

2.给对象添加属性和方法

给通过构造函数创建的对象添加属性和方法:在函数内部通过this给构造函数返回的对象添加属性。

function Person (name, age) {
    this.name = name;
    this.age = age;
}
var person1 = new Person();

通过构造函数的prototype属性给对象添加属性和方法,这种方式添加的属性和方法会被所有的对象实例共享。

function Person (name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function() {
    return this.name;
}
Person.prototype.breathes = ‘空气‘;
var person1 = new Person(‘张三‘, 20);
var person2 = new Person(‘李四‘, ‘21‘);
person1.sayName();

注意:一定要前在原型中定义方法和属性,然后再使用:

person2.eat();
Person.prototype.eat = function() {
    console.log(‘吃饭啦‘);
}

注意:原型对象中属性和对象自己的属性是有区别的,对象自己属性默认是可配置可枚举的,而我们在原型中添加的属性是不可配置的,但确是可枚举。

function Person (name, age) {
      this.name = name;
      this.age = age;
    }
    Person.prototype.sayName = function() {
        return this.name;
    }
    Person.prototype.breathes = ‘空气‘;

    var person1 = new Person(‘张三‘, 20);

    delete person1.sayName;

    console.log(person1.sayName())   // ‘张三‘

    for(propName in person1){
      console.log(propName)       // name age sayName breathes
    }

3.覆盖原型中属性

如果对象出现了和原型对象中同名的属性或方法,原型的属性和方法会被覆盖掉。这是因为,我们在访问对象的属性或方法时,优先在对象自己的属性列表中查找,如果找到的话,就使用自己的属性,如果找不到的,就去原型对象中查找。

在下面的示例中,原型对象中sayName方法被对象自己的sayName方法遮挡住了,所以最终调用的是对象自己的sayName方法。

function Person (name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function() {
    return this.name;
}

var person1 = new Person(‘李四‘, 20);
person1.sayName = function() {
    console.log(‘对象自己的sayName方法‘)
}
person1.sayName();      // ‘对象自己的sayName方法‘

4.hasOwnProperty()方法和in操作符的区别

判断对象中是否存在某个属性,除了使用in操作符,还可以使用hasOwnProperty()方法。hasOwnProperty()方法只在对象自己的属性列表中搜索;而in操作符,先在对象自己的属性列表中查找,如果找不到,接着去原型对象的属性列表中查找。

function Person (myname, myage) {
  this.name = myname;
  this.age = myage;

}
Person.prototype.sayName = function() {
  console.log(this.name)
}
var person1 = new Person(‘小明‘, 18, ‘女‘);
// 使用hasOwnProperty()方法
console.log(person1.hasOwnProperty(‘name‘))     // ture
console.log(person1.hasOwnProperty(‘sayName‘))  // false
// 使用in操作符
console.log(‘sayName‘ in person1)               // true

5.isPrototypeOf()方法

该方法是用来判断一个对象是否是另一个对象的原型。例如:

var monkey = {
    feeds: ‘香蕉‘,
    breathes: ‘空气‘
}

function Human (name) {
    this.name = name;
}

Human.prototype = monkey;
接下来我们来判断monkey对象是否是Human原型:

var person1 = new Human(‘李四‘);
monkey.isPrototypeOf(person1)
验证person1的原型是否是monkey

console.log(Object.getPrototypeOf(person1))
console.log(Object.getPrototypeOf(person1) === monkey)

6.proto

我们先前讲过,当我们访问一个当前对象中没有的属性时,会去prototype对象中查找。

var developer = new Human(‘李四‘);
developer.feeds = ‘大米饭‘;
developer.hacks = ‘JavaScript‘;

developer.hacks     // ‘JavaScript‘

当我们访问developer对象中不存在的breathes属性时,就会去原型对象中查找,仿佛有一个神秘的链接指向原型对象。

developer.breathes;  // ‘air‘

在大多数浏览器中都是以__proto__属性作为这个神秘的链接

console.log(developer.__proto__ === monkey);  // true

在学习的过程中,我们可以使用这个链接,但是在实际的项目开发中不要使用它,因为并不是所有的浏览器都有__proto__属性。

我们可以使用Object.getPrototypeOf()代替它。

7.扩展(增强)内置的构造函数创建的对象

内置的构造函数有ArrayStringObjectFunction等,我们可以通过改变原型对象的方式增强由这些构造函数创建的对象。

例如,给数组添加一个inArray()方法,用于判断数组中是否包含某个元素:

Array.prototype.inArray = function (ele) {
for (var i = 0; i < this.length; i++) {
  if(this[i] === ele) {
    return true;
  }
}
return false;
};
var colors = [‘red‘, ‘green‘, ‘blue‘];
console.log(colors.inArray(‘red‘));        // true
console.log(colors.inArray(‘purple‘));     // false
时间: 2024-10-20 01:11:48

这样理解原型,更加容易易懂的相关文章

理解原型对象

理解原型对象: 创建函数的时候,会为该函数创建一个prototype属性,这个属性指向函数的原型对象.默认情况下所有的原型对象都会获得一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针. 自己的理解,函数是一个对象 ,原型对象也是一个对象,我们在创建函数的时候就会自动为该函数创建一个原型对象,这两个对象怎么关联呢,在创建函数的时候默认就为函数创建了一个属性prototype(其实是指针)这个属性指向原型对象.那么这样函数就和他的原型对象关联起来了.那么这是函

node.js javascript理解原型继承

util.inherits util.inherits(constructor, superConstructor)是一个实现对象间原型继承的函数. JavaScript 的面向对象特性是基于原型的,与常见的基于类的不同.JavaScript 没有提供对象继承的语言级别特性,而是通过原型复制来实现的 var util = require('util'); function Base() { this.name = 'base'; this.base = 1991; this.sayHello =

以“一个公式” 的角度理解原型链

米娜桑,哦哈哟~ 原型链,已经是一个老生常谈的话题了,这里就不过多总结,精华一张图就可以搞定.该文章更多的是从 一个公式 的角度讲述原型链. 补充说明 实例化:用类(class)创建对象(obj)的过程. 如:TensionMax = new Person(),那么 TensionMax 是 Person 的实例(对象). 但由于 JavaScript 并不存在类,所以 JavaScript 所谓的类,只是我们模拟出来的函数,最终还是基于原型构建. 以下 3 个观点只是为了更方便快捷地理解原型链

javascript高级篇——理解原型和作用域【连载中...】

说明: 该教程绕开了javascript的一些基本的语法知识,直接讲解javascript中最难理解的两个部分,也是和其他主流面向对象语言区别最大的两个部分--原型和作用域,当然,肯定少不了原型链和作用域链.帮你揭开javascript最神秘的面纱. 为什么要偏偏要讲这两个知识点? 这是我在这么多年学习javascript的经历中,认为最难理解.最常犯错的地方,学习这两个知识点,会让你对javascript有更深层次的理解,至少理解了原型和作用域,就不能再算是javascript菜鸟了.另外,这

理解原型Prototype、继承

原型一直都是js中比较难理解的一块,那么原型究竟是什么,原型链又是什么? 原型Prototype是指当我们只要创建一个新的函数,就会根据特定的规则为这个函数创建一个prototype属性,这个属性指向函数的原型对象,原型对象通过其自身的constructor属性中的指针又指向拥有prototype属性的函数,也可以说是构造函数. 原型链是指如果让一个函数a的原型对象等于另一个类型b的实例,那么此时的a的原型对象就包含一个指向b的原型对象的指针,相应的,b的原型中包含指向构造函数b的指针,如果b的

【JavaScript】类继承(对象冒充)和原型继承__深入理解原型和原型链

JavaScript里的继承方式在很多书上分了很多类型和实现方式,大体上就是两种:类继承(对象冒充)和原型继承. 类继承(对象冒充):在函数内部定义自身的属性的方法,子类继承时,用call或apply实现对象冒充,把类型定义的东西都复制过来,这样的继承子类与父类并没有多少关联,不互相影响,有利于保护自身的一些私有属性. 原型继承:每个函数都有自己的原型(prototype)属性,这个属性是在生成实例对象时自动创建的.它本身又是一个对象,拥有能够在实例间共享的属性和方法.而实例本身的属性和方法,则

理清javascript中prototype、__proto__、Object、Function的关系,更好地理解原型继承

本文参考了http://www.blogjava.net/heavensay/archive/2013/10/20/405440.html这篇文章,对其内容作了个简单总结,形成了几条简单的结论,让读者更容易记住prototype.__proto__.Object.Function之间的关系. 结论1:Object.prototype只是一个普通对象,它是js原型链的最顶端. (typeof Object.prototype) === object;//true Object.prototype.

三分钟理解“原型模式”——设计模式轻松掌握

原型模式的官方定义: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 大白话: 现在有一个类,它要产生大量的对象,而且这些对象中的属性值大部分都相同:如果我们要获取这样一个对象的时候每次都通过new,然后再set每一个属性值,那么这样就太麻烦了.这种情况下使用原型模式非常便捷: 我们让这个类去实现ICloneable接口,并且实现该接口的clone()函数,在clone函数中让当前对象进行一次浅拷贝/深拷贝,总之就是克隆一个当前对象来,这样我们就无需new完了对象后再逐个set

JavaScript - 理解原型

Function对象特有的属性 prototype 所有对象都有的属性 __proto__ 1.用法 const F = function (name) { this.name = name } F.prototype.greeting = function () { console.log('hello', this.name) } let f1 = new F('osyo') let f2 = new F('mioco') f1.greeting() // hello osyo f2.gre