Javascript中的继承与Prototype
之前学习js仅仅是把w3school上的基本语法看了一次而已,再后来细看书的时候,书中会出现很多很多没有听过的语法,其中一个就是js的继承以及总能看到的prototype。我主要在看的两本js书是《javascript权威指南》,也就是那本犀牛书,还有一本是疯狂xx系列的《疯HTML5/CSS3/Javascript讲义》。前者非常适合用啃js细节,如果需要深入学习一些js内部机制以及相关的内容,这本大块头啃起来还是挺有味道的。后者是本速成教材,可以让你对某个概念有一个非常舒服的打开方式,不晦涩,浅显易懂。大家如果看完w3school之后,感觉没有学到什么东西的话,应该试着去看看书,这是我刚开始学习前端总结出来的小建议。
先说说继承,在js里面其实是没有继承的概念。但大家应该都知道,在面向对象的程序设计里,类之间有显示的继承关系,一个类可以显示地指定继承自哪一个类,然后继承下来的子类就会有父类的属性和方法。js里没有这一概念,但是它一种类似继承的方法来对原来的类进行扩展。这种方式就是通过类的prototype属性,来为类动态增加属性和方法,这种方式类似于继承,但它只能称作是“伪继承”,因为这种继承的实质是修改了原有的类,而不是产生一个子类。
我们先说不用继承的时候,js通过什么样的方法来为对象增加属性和方法呢。
首先,程序为一个对象的并不存在属性进行赋值的时候,就可以认为是为这个对象增加了属性。
【代码01】
var obj = {};
obj.name = "Jeremy";
obj.info = function(){
console.log("This is a method");
}
在这里插入说明一下函数、方法、对象还有类的概念理解。
函数,在javascript里面有“一等公民”之称,当在js中定义了一个函数之后,其实就是生成了以下:
1)函数:类似于java的方法,它可以被调用;
2)对象:当定义了一个函数时候,系统也就创建了一个对象,这个对象是Function类的实例;
3)方法:定义了一个函数的时候,这个函数会被附加给某个对象,作为某个对象的方法:
【代码02】
function Person(name,gender){
var val = "valueName";//局部变量
this.name = name;
this.gender = gender;
//定义了一个匿名函数。相当于为Person对象指定了info方法
this.info = function(){
console.log("name:"+this.name);
console.log("gender:"+this.gender);
console.log("val:"+val);
}
}
var p1 = new Person('Jeremy','male');
//实例p1去调用方法info()
var v = p1.info();
console.log("这里能访问到局部变量val:"+v);
4)类:在定义函数的同时,即得到一个和函数同名的类,而这个函数就是该类的构造器,所以在定义一个函数的时候,实际
就是定义了一个构造器。
我们来看上面的【代码02】。
程序定义了一个函数Person,同时也就定义了Person类,函数即类的构造器,这个函数为Person实例p1提供了info方法。
虽然这样我们也完成了对Person的方法增加,但是这样做会存在一些问题。例如性能会低下,每次创建Person对象的时候就会有很多info函数,这样会造成系统内存泄漏(实际是什么情况我暂时没有去探究了),引起性能下降。还有一个很明显的问题,知道js闭包的朋友应该发现了,在info()函数里访问局部变量val,形成了闭包(这里不对闭包展开说了)。然而这会导致val变量的作用域扩大,在代码末尾,程序依旧可以访问到局部变量值。
所以!为了避免这些不好的事情的发生!建议使用prototype属性。
首先在javascript中,每一个javascript对象(null除外)都会和另外一个对象相关联,这个另一个对象就是原型,js中的每一个对象都是从原型那里继承属性。在创建对象的3种方法里面,通过对象直接量创建的对象都具有同一个对象原型,可以通过Object.prototype获得对对象原型的引用。通过关键字new和构造函数创建的对象的原型即使构造函数的prototype的值。所以,和使用var empty={};创建对象一样,通过new Object()创建的对象也继承自Object.prototype。
【对象直接量创建对象】即由若干的名/值对组成的映射表。就像这样:
var empty={};//属性为空的对象
var person={name:"gua",age:"18"};//具有name和age属性的值
【new关键字创建对象】通过new关键字创建并初始化一个新的对象。形式上就是new后面跟一个函数调用,这里的函数称作构造函数(constructor),这个构造函数用于初始化一个新创建的对象。就像这样:
var obj = new Object();
var arr = new Array();
换个好理解一些的说法,就是js对象都是有相同基类(object)的实例。 嗯,我也觉得这一段比较晦涩。 那来看一下代码是怎么实现的就好了。
function Person(name,gender){
this.name = name;
this.gender = gender;
//定义了一个匿名函数。相当于为Person对象指定了info方法
this.info = function(){
console.log("name:"+this.name);
console.log("gender:"+this.gender);
}
}
var p1 = new Person('Jeremy','male');
p1.info();
//为Person类的prototype属性增加了walk函数,即可以认为为Person类动态增
//加walk实例方法
Person.prototype.walk = function(){
console.log(this.name +" 正在散步.......一步一步.....");
}
var p2 = new Person('Guagua','female');
p2.info();
//执行p2的walk方法
p2.walk();
//js已经为类Person动态增加了方法walk,所以p1也具有了walk方法。
p1.walk();

这段程序采用prototype为Person类增加了一个walk方法,这让所有的Person实例共享了一个walk方法,而walk方法并不在Person函数之内,所以就不会产生闭包。所以我们应该避免使用内嵌函数为类定义方法,使用增加prototype属性的方式来增加方法。
以上是我最近看书学习整理出来的一些内容,有不对的地方望大家指正。
Javascript中的继承与Prototype的更多相关文章
- 关于JavaScript中实现继承,及prototype属性
感谢Mozilla 让我弄懂继承. JavaScript有八种基本类型,函数属于object.所以所有函数都继承自object.//扩展:对象,基本上 JavaScript 里的任何东西都是对象,而且 ...
- 深入了解JavaScript中基于原型(prototype)的继承机制
原型 前言 继承是面向对象编程中相当重要的一个概念,它对帮助代码复用起到了很大的作用. 正文 Brendan Eich在创建JavaScript时,没有选择当时最流行的类继承机制,而是借鉴Self,用 ...
- JavaScript学习13 JavaScript中的继承
JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式 ...
- 浅谈JavaScript中的继承
引言 在JavaScript中,实现继承的主要方式是通过原型链技术.这一篇文章我们就通过介绍JavaScript中实现继承的几种方式来慢慢领会JavaScript中继承实现的点点滴滴. 原型链介绍 原 ...
- JavaScript中的继承(原型链)
一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.pro ...
- 彻底搞懂JavaScript中的继承
你应该知道,JavaScript是一门基于原型链的语言,而我们今天的主题 -- "继承"就和"原型链"这一概念息息相关.甚至可以说,所谓的"原型链&q ...
- 浅谈 JavaScript 中的继承模式
最近在读一本设计模式的书,书中的开头部分就讲了一下 JavaScript 中的继承,阅读之后写下了这篇博客作为笔记.毕竟好记性不如烂笔头. JavaScript 是一门面向对象的语言,但是 ES6 之 ...
- javascript中各种继承方式的优缺点
javascript中实现继承的方式有很多种,一般都是通过原型链和构造函数来实现.下面对各种实现方式进行分析,总结各自的优缺点. 一 原型继承 let Super = functioin(name = ...
- javascript中实现继承的几种方式
javascript中实现继承的几种方式 1.借用构造函数实现继承 function Parent1(){ this.name = "parent1" } function Chi ...
随机推荐
- js-权威指南学习笔记16
1.元素的style属性可以用来设置样式,但是不适合用来查询样式(只能查询到内联样式). 2.CSS里的层叠指示了应用于文档中任何给定元素的样式规则是各个来源的层叠效果:Web浏览器的默认样式表.文档 ...
- gotop(返回顶部)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- SLAM会被深度学习方法取代吗?
日益感觉到自己对深度学习的理解比较肤浅,这段且当做是以前的认识. 上上周去围观了泡泡机器人和AR酱联合举办的论坛.在圆桌阶段,章国峰老师提了一个问题:SLAM会被深度学习方法取代吗?这是一个很有趣的话 ...
- Android属性动画简单剖析
运行效果图: 先看布局文件吧,activity_main.xml: <?xml version="1.0" encoding="utf-8"?> & ...
- SQL注入 payload 记录
使用 REGEXP盲注 payload select user() from users where user_id=1 and (select(user)from users where user_ ...
- 关于jsp页面中时间显示问题
首先说明一下情况,在MySQL数据库中获取的时间显示在jsp页面中不是按指定格式显示,显示的是类似于这种--Tue Jun 18 00:00:00 CST 2013.而想要的仅仅是年月日而已. 对于这 ...
- maven 骨架命令行创建
项目的骨架maven 约定在项目的根目录下放置pom.xml,在src/main/java目录下放置主代码,在src/test/java下放置项目的测试代码. 这些基本的目录结构和pom.xml文件的 ...
- Django ORM字段类型 单表增删改查 万能的双下划线
1.ORM三种模型 模型之间的三种关系:一对一,一对多,多对多. 一对一:实质就是在主外键(author_id就是foreign key)的关系基础上,给外键加了一个UNIQUE=True的属性: 一 ...
- MySQL中如何实现select top n
用惯了access mssql server的朋友,可能在用mysql查询前N条记录时,习惯的使用select top n 形式的语句,在这里说明一下,mysql没有此语法,mysql用limit来实 ...
- Python初学者第二十四天 函数进阶(3)生成器
24day 1.列表生成式: 循环模式:[变量(加工后的变量) for 变量 in iterable] print([i for i in range(0,101,2)]) [1,4,9,16,25, ...