在我学习与使用javascript三个月中,我一直对javascript的继承关系以及prototype理解不清,导致很多时候为什么这么用说不出个所以然来。截止到本周为止,通过之前的学习以及自己的再学习,自我感觉算是对这一块有了较为清晰的认识,此文将谈谈我对javascript原型与继承的理解,在此之前,我们首先要知道一些基本的知识。

   知识铺垫

  1、数据类型

  JavaScript中的数据类型在曾经我也有提到过,它包括未定义值(undefined),空值(null),布尔值(boolean),数字(number),字符串(string)以及对象(object),而对象中又包含特殊对象数组(array),并且函数也是对象。其中,字符串(string),对象(object)等都是由构造函数来实现的。讲到这里又得说说JavaScript中的函数了。

  2、函数

  就我所知的语言都是有函数这个概念的,所以就不再细说。

  在 JavaScript 中函数也是一个对象,那么对象又是通过什么来创建的呢?对象是作为现有示例(即原型)对象的副本而创建的,该名称就来自于这一概念,此原型对象的任何属性和方法都将显示为从原型的构造函数创建的对象的属性和方法。可以说,这些对象从其原型继承了属性和方法。

  普通的函数与构造函数在JavaScript中都是通过function来创建,不同的是构造函数需要通过大写来标明。例如:

 function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.say = function () {
console.log('my name is ' + this.name + ",I'm " + this.age )
}
} Person.say_hello = function () {
console.log("Hello,I'm" + this.sex)
}; Person.prototype.is_alive = function () {
return true
}; var wfsovereign = new Person('wfsovereign', 21, "boy"); wfsovereign.say(); //output my name is wfsovereign,I'm 21
console.log(wfsovereign.is_alive()); //output true
console.log(wfsovereign.say_hello(),"----"); //output undefined

  此例中,创建了构造函数Person,接受参数为name,age,拥有静态方法say_hello(),实例方法say()和is_alive(),使用构造函数创建实例对象wfsovereign,能够调用实例方法,调用静态方法时提示未定义。

  在构造函数后通过"."来添加的方法或属性,称之为静态方法或静态属性,这是实例之后的对象不能访问的。因此,我们通过wfsovereign调用say_hello()时才会提示undefined。

  那么,我们写在构造函数的prototype上的方法is_alive()为什么实例过后仍然能够被访问呢?这个问题我们先放放,先来看看实例对象与构造函数间的联系,通过控制台,我们输出

 console.log(wfsovereign.prototype);
console.log(wfsovereign.__proto__);
console.log(wfsovereign.constructor);

  可以看到

 undefined    //wfsovereign.prototype

 Person {is_alive: function}    //wfsovereign.__proto__)
constructor: function Person(name, age, sex) {
is_alive: function () {
__proto__: Object function Person(name, age, sex) { //wfsovereign.constructor
this.name = name;
this.age = age;
this.sex = sex;
this.say = function () {
console.log('my name is ' + this.name + ",I'm " + this.age )
}
}

  可以看到,实例对象wfsovereign没有prototype属性,但是有了指向构造函数Person.prototype的__proto__属性以及指向构造函数的constructor属性,而Person这一构造函数也有指向object的__proto__属性,说明Person也是通过object创建的一个实例。这个时候我相信聪明如你就能回答上面提出的问题了—我们写在构造函数的prototype上的方法is_alive()为什么实例过后仍然能够被访问呢?

  由此,我们得出,创建的每一个函数都有prototype属性,这是一个指针,它指向一个对象,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。也就是说prototype是通过调用构造函数而创建的那个对象实例的原型对象,并且只有函数才有prototype属性,实例的对象没有该属性,即这里用Person创建的实例wfsovereign是没有prototype这一属性的。

  当使用构造函数(Person)创建一个实例(wfsovereign)的时候,实例内部将包含一个内部指针(__proto__)指向构造函数的prototype,这个连接存在于实例和构造函数的prototype之间,而不是实例与构造函数之间,实例与构造函数之间通过constructor连接。知道了prototype是什么和怎么来的之后,我们再来看JavaScript的原型链就容易多了。

   继承与原型链

  1、原型链的理解

  JavaScript 不包含传统的类继承模型,而是使用 prototype 原型模型。在JavaScript中,一共有两种类型的值,原始值和对象值。每个对象都有一个内部属性 prototype ,我们通常称之为原型。原型的值可以是一个对象,也可以是null。如果它的值是一个对象,则这个对象也一定有自己的原型。当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或方法,就会自己去关联的prototype对象那里寻找,如果prototype没有,就会去关联的创造者那里找,直到prototype为undefined为止,Object的prototype就是undefined即所有原型都终止于 Object.prototype,这样就形成了一条线性的链,我们称之为原型链。JavaScript正是通过原型链来调用关联创造者的属性与方法的即继承。

  2、使用原型的好处

  可以让对象实例共享它所包含的属性和方法。也就是说,不必在构造函数中添加定义对象信息,而是可以直接将这些信息添加到原型中,通过指针引用的方式来调用。使用构造函数的主要问题就是每个方法都要在每个实例中创建一遍。

  

ps:本文内容若是有误或者迷糊,还请指正或指出。

浅谈系列之 javascript原型与对象的更多相关文章

  1. javaScript系列 [03]-javaScript原型对象

    [03]-javaScript原型对象 引用: javaScript是一门基于原型的语言,它允许对象通过原型链引用另一个对象来构建对象中的复杂性,JavaScript使用原型链这种机制来实现动态代理. ...

  2. 浅谈JS中的原型对象和原型链

    我们知道原型是一个对象,其他对象可以用它实现属性继承,除了prototype,又有__proto__ 1. prototype和__proto__的区别 prototype是函数才有的属性      ...

  3. 浅谈模块化的JavaScript

    模块化JavaScript之风早已席卷而来, CommonJS . AMD . NodeJS .RequireJS . SeaJS . curljs  等模块化的JavaScript概念及库扑面而来, ...

  4. JavaScript 原型和对象创建底层原理

    1. prototype/__proto__/constructor JS原型链和继承网上已经烂大街了,5毛可以买一堆,这里只提一下: constructor:普通对象和函数对象都有,指向创建它的函数 ...

  5. 浅谈 ECMAScript 和 JavaScript

    ES5与ES3基本保持兼容,较大的语法修正和新功能加入,将由JavaScript.next完成. 什么是ECMAScript?http://baike.baidu.com/link?url=G1T8n ...

  6. 浅谈Java和JavaScript中变量和数据类型的区别

    对于一门编程语言的学习,如果第一步是安装环境,那么第二步一定是学习这门语言的基本规则,变量和数据类型则首当其冲 JavaScipt作为一个蹭Java热度而命名的语言,在很多方面和Java也有一定的相似 ...

  7. 浅谈ListBox控件,将对象封装在listBox中,在ListBox中显示对象中某个属性,在ListBox中移除和移动信息

    大家好,俗称万事开头难,不经历风雨,怎能见彩虹.在此小编给大家带来一个自己练习的小实例,希望与大家一起分享与交流.下面进入应用场景,从SQL2008数据库取出数据,给ListBox赋值在界面并显示出来 ...

  8. 浅谈Java虚拟机内存中的对象创建,内存布局,访问定位

    参考于 深入理解Java虚拟机 这里介绍HotSpot虚拟机(自带的虚拟机) 1.对象的创建 对于程序员来说,创建对象的方法: User user1 = new User(); User user2 ...

  9. 安卓开发_浅谈Fragment之事务添加Fragment对象

    我们都知道给一个activity动态添加fragment的时候 有下面几种添加方式 看一下布局文件 <LinearLayout xmlns:android="http://schema ...

随机推荐

  1. 前端css兼容性与易混淆的点

    一.常用的骨灰级清除浮动 .clearfix:after { content: "."; display: block; height:; clear: both; visibil ...

  2. 【AR实验室】ARToolKit之Example篇

    0x00 - 前言 PS : 我突然意识到ARToolKit本质可能就是一个可以实时求解相机内外参的解决方案. 拿到一个新的SDK,90%的人应该都会先跑一下Example.拿到ARToolKit的S ...

  3. iframe用法

    <iframe src="http://caiyanli.top/" height="500"  width="500" frameb ...

  4. wordpress多站点配置

    wordpress作为全球第一的个人博客搭建平台一直在国内外有着较高的人气,从3.0版本开始就已经支持多站点的搭建.该功能可以让子站点运行主站点的程序,不需要再每个站点分别存放网站程序.最近更新的4. ...

  5. gulp详细入门教程

    本文链接:http://www.ydcss.com/archives/18 gulp详细入门教程 简介: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优 ...

  6. 数据图表插件Echarts(一)

    一.引言 最近做一个智慧城市项目,项目中需要图表和报表进行数据分析,从网上找了很多,最后找到了百度开放的echarts,一个很强大的插件. 二.介绍 ECharts,缩写来自Enterprise Ch ...

  7. 使用mybatis-generator在自动生成Model类和Mapper文件

    使用mybatis-generator插件可以很轻松的实现mybatis的逆向工程,即,能通过表结构自动生成对应的java类及mapper文件,可以大大提高工作效率,并且它提供了很多自定义的设置可以应 ...

  8. 自己写的数据交换工具——从Oracle到Elasticsearch

    先说说需求的背景,由于业务数据都在Oracle数据库中,想要对它进行数据的分析会非常非常慢,用传统的数据仓库-->数据集市这种方式,集市层表会非常大,查询的时候如果再做一些group的操作,一个 ...

  9. [WPF] Wait for a moment.

    一.控件介绍 在 WPF 中使用的等待控件,控件包括三种,普通的等待信息提示(WaitTip),进度条提示(WaitProgress),以及主程序覆盖的模拟时钟等待窗口(WaitClock),具体效果 ...

  10. 微信公众号开发(一)--验证服务器地址的Java实现

    现在主流上都用php写微信公众号后台,其实作为后端语言之一的java也可以实现. 这篇文章将对验证服务器地址这一步做出实现. 参考资料:1.慕课网-<初识java微信公众号开发>,2.微信 ...