原型与原型链

一. 普通对象与函数对象
  • JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Object 、Function 是 JS 自带的函数对象。下面举例说明
var o1 = {};
var o2 = new Object();
var o3 = new f1(); function f1(){};
var f2 = function(){};
var f3 = new Function('str'); typeof Object;//function
typeof Function;//function typeof f1;//function
typeof f2;//function
typeof f3;//function typeof o1;//object
typeof o2;//object
typeof o3;//object

在上面的例子中 o1 o2 o3 为普通对象,f1 f2 f3 为函数对象。怎么区分,其实很简单,凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。f1,f2,归根结底都是通过 new Function()的方式进行创建的。Function Object 也都是通过 New Function()创建的。

二.构造函数
function Person(name, age, job){
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name);
}
}
var person1 = new Person('mike',15);
var person2 = new Person('nike',18);

上例中person1和person2为Person的实例,两个实例中都有隐含的

constructor属性(通过原型对象继承得到),该属性指向构造函数Person

三.原型对象
  • 我们创建的每个函数都有一个prototype(原型)属性,指向函数的原型对象。换句话说,prototype就是通过调用构造函数而创建的那个对象实例的原型对象,使用原型对象即可以让所有对象实例共享它所包含的属性和方法,可类比于父子类(继承)。
  • 创建新函数时,其prototype属性指向的原型对象会自动获得一个constructor(构造函数)属性,该属性指向包含prototype的函数,也就是构造函数
function Person(name, age, job){
Person.prototpe.name = father;
Person.prototpe. = 28;
Person.prototpe.sayName = function(){
alert(this.name);
}
}
var person1 = new Person();
person1.sayName();//'mike'
var person2 = new Person();
person2.sayName();//'nike' person1.sayName == person2.sayName;//true person1.name = 'joy';
person1.sayName();//'joy'

通过为构造函数Person的原型对象创建属性,person1,person2将继承Person.prototype的属性,如果实例定义了与原型对象同名属性,原型对象属性则会被覆盖。

补充:更简单的原型语法
function Person(){}
Person.prototype = {
name:'',
age:'',
sayName:function(){
}
}

注意:该方法的原型对象的constructor属性不再指向Person,此时例中指向Object(新new的一个对象),如若需要可在Person.pertotype的字面量中添加:constructor:Person,

四.__proto__
  • JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__ 的内置属性,用于指向创建它的构造函数的原型对象。

  • 普通对象的__proto__指向这个对象(this)的构造函数的prototype;

  • 函数对象的__proto__全部都是指向Function的prototype。

对象 person1 有一个 __proto__属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype ,所以:

person1.__proto__ == Person.prototype

不过,要明确的真正重要的一点就是,这个连接存在于实例person1与构造函数Person的原型对象Person.prototype之间,而不是存在于实例person1与构造函数Person之间。

js高级程序设计图

五.Prototype

当我们创建一个函数时:

var Person = new Object()

Person 是 Object 的实例,所以 Person 继承了Object 的原型对象Object.prototype上所有的方法:

六.Object.getPrototypeOf(obj)

获取对象的原型

总结
  • 原型和原型链是JS实现继承的一种模型。

  • 原型链的形成是真正是靠__proto__ 而非prototype

  • 对象通过__proto__属性访问原型,构造函数通过prototype属性访问原型

  • Object 是所有对象的爸爸,所有对象都可以通过 proto 找到它

  • Function 是所有函数的爸爸,所有函数都可以通过 proto 找到它

  • Function.prototype 和 Object.prototype 是两个特殊的对象,他们由引擎来创建

  • 除了以上两个特殊对象,其他对象都是通过构造器 new 出来的

  • 函数的 prototype 是一个对象,也就是原型

    对象的 proto 指向原型, proto 将对象和原型连接起来组成了原型链

JavaScript对象——原型与原型链的更多相关文章

  1. 细说JavaScript对象(2):原型对象

    JavaScript 并没有类继承模型,而是使用原型对象 prototype 进行原型式继承. 尽管人们经常将此看做是 JavaScript 的一个缺点,然而事实上,原型式继承比传统的类继承模型要更加 ...

  2. JavaScript中的原型与原型链

    一直对JavaScript的原型与继承不了解,参考<JavaScript权威指南(第六版)>和<JavaScript高级程序设计(第三版)>对这个点的知识做个整理,方便自己记忆 ...

  3. 25 JavaScript对象原型&ES5新的对象方法

    JavaScript对象原型 所有JavaScript对象都从原型继承对象和方法 日期对象继承自Date.prototype,数组继承自Array.prototype,对象构造器新建的对象Person ...

  4. 细说JavaScript对象(4): for in 循环

    如同 in 运算符一样,使用 for in 循环遍历对象属性时,也将往上遍历整个原型链. // Poisoning Object.prototype Object.prototype.bar = 1; ...

  5. 细说JavaScript对象(3):hasOwnProperty

    判断一个属性是定义在对象本身而不是继承自原型链,我们需要使用从 Object.prototype 继承而来的 hasOwnProperty 方法. hasOwnProperty 方法是 JavaScr ...

  6. 细说JavaScript对象(1):对象的使用和属性

    JavaScript 中的一切都可以视为对象,除了两个特例:null 和 undefined. false.toString(); // 'false' [1, 2, 3].toString(); / ...

  7. javascript中的对象,原型,原型链和面向对象

    一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...

  8. 理解 JavaScript 对象原型、原型链如何工作、如何向 prototype 属性添加新的方法。

    JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板.从原型继承方法和属性.原型对象也可能拥有原型, ...

  9. JavaScript对象原型链的学习

    1.构造函数和原型 1.1对象的三种创建方式 字面量方式 var obj = {}; new关键字 var obj = new Object(); 构造函数方式 function Person(nam ...

随机推荐

  1. 基于docker创建的Jenkins,settings.xml文件放在哪里

    如果运行容器时挂载目录如下 启动容器 docker run -itd -p 8080:8080 -p 50000:50000 --name jenkins --privileged=true  --r ...

  2. asp.net 类头部描述

    这里教大家怎么在新建类的时候默认有头部描述,先看效果: 像这样的内容我们要怎么进行添加呢? 前方高能...... 找到VS的安装目录-->比如我自己的安装目录D:\VS2013\Common7\ ...

  3. C#学习(1):类型约束

    where T : class泛型类型约束 类型参数约束,.NET支持的类型参数约束有以下五种: where T : struct | T必须是一个结构类型 where T : class T必须是一 ...

  4. JAVA-WEB开发环境和搭建

    JAVA Web开发环境与搭建 一.下载安装JDK 1.配置jdk开发环境 JAVA_HOME 2.path 二.下载安装eclipse javaEE版本 三.安装部署tomcat 3.1.安装: 直 ...

  5. “全栈2019”Java第一百章:局部内部类可以实现接口吗?

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. mylyn提交到JIRA的日期格式错误

    HTTP Status 400 - Date value '27/Dec/11' for field 'due' is invalid. Valid formats include: 'yyyy/MM ...

  7. 《快学Scala》第八章 继承

  8. 【Qt】VS2010编译Qt5.3.2 64bit

    1. 为什么要这么做 在Windows下,Qt官网默认提供的二进制版本大多是32位,目前(2015.01.24)只对VS2013提供了64位版本,如下图所示: 为了适应我目前安装的VS2010 IDE ...

  9. collections 模块常用方法学习

    前情提要: 1:模块介绍 个人认为就是 python自带的骚操作模块.如果基础能力够给力的话,完全用不到 个人认为解析式才是装逼神奇,用模块的都是伪娘 2:deque   双向列表 from coll ...

  10. 编程开发之--java多线程学习总结(1)问题引入与概念叙述

    1.经典问题,火车站售票,公共票源箱,多个窗口同时取箱中车票销售 package com.lfy.ThreadsSynchronize; /** * 解决办法分析:即我们不能同时让超过两个以上的线程进 ...