【Javascript】Javascript原型与继承
一切都是对象!
以下的四种(undefined, number, string, boolean)属于简单的值类型,不是对象。剩下的几种情况——函数、数组、对象、null、new Number(10)都是对象。他们都是引用类型。
判断一个变量是不是对象非常简单。值类型的类型判断用typeof,引用类型的类型判断用instanceof。
var fn = function () { };
console.log(fn instanceof Object); // true
java中的对象都是new一个class出来的,而且里面有字段、属性、方法,规定的非常严格。但是javascript就比较随意了,数组是对象,函数是对象,对象还是对象。对象里面的一切都是属性,只有属性,没有方法。那么这样方法如何表示呢?方法也是一种属性。因为它的属性表示为键值对的形式。而且javascript中的对象可以任意的扩展属性,没有class的约束。
在javascript中,一切(引用类型)都是对象,对象是属性的集合。
一切对象都是通过函数创建的!
譬如:
var obj = {a: 1, b: 2},
var mm = {12, 'X', false}
实质上的本质为:
var obj = new Object();
obj.a = 1;
obj.b = 2; var mm = new Array();
mm[0] = 12;
mm[1] = X;
mm[2] = false;
其中的Object和Array都是函数。
上面的写法其实是下面写法的一种"便捷方式"。
原型 prototype
!每一个函数都有一个默认属性“prototype”。
前面说过,每一个函数都是一种对象,都是属性的集合,你可以对函数进行自定义属性。Javascrpit默认给每一个函数一个默认属性---prototype。
这个prototype的属性值是一个对象(属性的集合),默认的只有一个叫做constructor的属性,指向这个函数本身。

当然,prototype作为一个对象,属性的集合,也可以自定义的增加许多属性。
function Fn() { }
Fn.prototype.name = 'Tom';
Fn.prototype.getYear = function () {
return 1988;
};
隐式原型 _proto_
!每一个对象都有一个隐藏的属性“_proto_”,这个属性引用了创建这个对象的函数的prototype。即:fn.__proto__ === Fn.prototype.
这里的"__proto__"称之为“隐式原型”。

在上面的这张图中可以看出来,自定义函数Foo.__proto__指向Function.prototype,Object.__proto__指向Function.prototype。Function也是一个函数,函数是一种对象,也有__proto__属性。既然是函数,那么它一定是被Function创建。所以——Function是被自身创建的。所以它的__proto__指向了自身的Prototype。
每个对象都有一个__proto__属性,指向创建该对象的函数的prototype。而每个函数的prototype也是一个对象,他同样有一个_proto_属性,其本质上与var obj = {} 是一样的,都是被Object创建,所以它的__proto__指向的就是Object.prototype。
而Object.prototype的_protype属性比较特殊,它指向的是一个null值。
typeof & instanceof
对于值类型,你可以通过typeof判断,string/number/boolean都很清楚,但是typeof在判断到引用类型的时候,返回值只有object/function,你不知道它到底是一个object对象,还是数组,还是new Number等等,这个时候就需要用到instanceof。

Instanceof运算符的第一个变量是一个对象,暂时称为A;第二个变量一般是一个函数,暂时称为B。
Instanceof的判断队则是:沿着A的__proto__这条线来找,同时沿着B的prototype这条线来找,如果两条线能找到同一个引用,即同一个对象,那么就返回true。如果找到终点还未重合,则返回false。
比如:
console.log(Object instanceof Function);
console.log(Function instanceof Object);
console.log(Function instanceof Function);
结果都为true。
而如何理解instanceof的作用呢?
其实instanceof表示的就是一种继承关系,或者原型链的结构。
继承 & 原型链
“继承”是常用面向对象语言中最基本的概念,但是java中的继承与javascript中的继承又完全是两回事儿。
javascript中的继承是通过原型链来体现的。
如下面的代码:
function Foo() {};
var f = new Foo();
f.name = 'Cat';
Foo.prototype.name = 'Tom';
Foo.prototype.sex = 'Man'
console.log(f.name);
console.log(f.sex);
结果:

访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链。
在上例中,访问f.sex时,f的基本属性中没有sex,于是沿着__proto__找到了Foo.prototype.sex。
我们在实际应用中如何区分一个属性到底是基本的还是从原型中找到的呢?答案是——hasOwnProperty。譬如: if (f.hasOwnProperty(X)){}。
而问题又出来了,在f中是没有hasOwnProperty这个方法的,那这个方法是从哪里来的呢?
其实他是从Object.prototype中得到的。对象的原型链是沿着__proto__这条线走的,因此在查找f.hasOwnProperty属性时,就会顺着原型链一直查找到Object.prototype。
由于所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。这就是所谓的“继承”。
ps:
如果继承得到的方法感觉不合适,你可以自己进行修改。
如果继承无法满足需要,还可以自己添加方法。不过如果你要添加内置方法的原型属性,最好做一步判断,如果该属性不存在,则添加。如果本来就存在,就没必要再添加了。
【Javascript】Javascript原型与继承的更多相关文章
- 【面试必备】javascript的原型和继承
原型.闭包.作用域等知识可以说是js中面试必考的东西,通过你理解的深度也就能衡量出你基本功是否扎实.今天来复习一下javascript的原型和继承,虽说是老生常谈的话题,但对于这些知识,自己亲手写一遍 ...
- 深入浅出JavaScript之原型链&继承
Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instanc ...
- javascript的原型和继承(1)
原型与继承是javascript中基础,重要而相对比较晦涩难解的内容.在图灵的网上看到一篇翻译过的文章,有参考了一些知名博客.我自己总结了几篇.通过这次的总结,感觉自己对原型和继承的认识又增加了很多, ...
- JavaScript的原型链继承__propt__、prototype、constructor的理解、以及他们之间相互的关系。
回想自己已经工作了有一段时间了,但是自己对JavaScript的原型链.和继承的理解能力没有到位,最近他们彻底的整理并且复习了一遍. 本案例中部分文案来自网络和书籍,如有侵权请联系我,我只是把我的理解 ...
- JavaScript 面向对象 原型(prototype) 继承
1.对象的概念:无需属性的集合,属性可以为数值,对象或函数,ECMAscript中没有类的概念,这点是javascript与其他面向对象(OO)语言不同的地方. //创建一个自定义对象 var per ...
- JavaScript基于原型的继承
在一个纯粹的原型模式中,我们会摒弃类,转而专注于对象,基于原型的继承相比基于类的继承的概念上更为简单 if( typeof Object.beget !== 'function') { Object. ...
- javascript的原型与继承(2)
这是上一篇的后续. Javascript是一种基于对象的语言,遇到的所有东西几乎都是对象.如果我们想要把属性和方法封装成一个对象,应该怎么做呢: 假设我们把猫看成一个对象: var Cat = { n ...
- javascript高级:原型与继承
原型继承的本质就是一条原型链,对象会沿着这条链,访问链里的方法属性. 对象的__proto__属性就是用于访问它的原型链的上一层: 考虑以下对象: 1. 所有对象的原型: Object.prototy ...
- 🍓JavaScript 对象原型链继承的弊端 🍓
- javascript中继承(一)-----原型链继承的个人理解
[寒暄]好久没有更新博客了,说来话长,因为我下定决心要从一个后台程序员转为Front End,其间走过了一段漫长而艰辛的时光,今天跟大家分享下自己对javascript中原型链继承的理解. 总的说来, ...
随机推荐
- CodeForces 834D The Bakery(线段树优化DP)
Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought required ingredient ...
- Mysql简介与编译安装
==========MYSQL工作原理图: 1>数据库简介:简单的说数据库(database)就是一个存储数据的仓库,它将数据按照特定的规律存储到磁盘上,通过数据库管理系统,能够有效的管理存储在 ...
- yum使用,使用rpm指令安装rpm,使用dpkg指令安装deb
yum安装时如果报错提示安装失败,缺少库文件,可以使用: yum whatprovides 库名 之后安装提供的程序 yum remove xxx卸载 yum update 更新 解决 Require ...
- tomcat 6.x + log4j日志配置并按天(或大小)生成文件
tomcat日志,默认路径在${catalina.home}/logs目录下,默认使用的是tomcat自己封装的logging工具类,默认配置文件使用的${catalina.home}/conf/ ...
- Nutch2.2.1 爬虫问题列表
http://www.cnblogs.com/cy163/archive/2013/02/14/2912630.html http://blog.csdn.net/wangzhaodong001/ar ...
- Spring Boot - Spring Cache
缓存 服务器自身(内存)的缓存 利用java程序中的变量 简单 集群环境中多个实例无法共享同步 缓存服务器(一般支持集群.分布式) Redis Memcached Spring中使用注解使用缓存 启动 ...
- nginx的conf文件,两种配置方式,第一种无ssl证书,第二种有ssl证书。
以下为无ssl证书配置的请求转发 server { listen 80; server_name api.******.com; location ~* /union { client_max_bod ...
- OCP 12c最新考试原题及答案(071-6)
6.(4-21) choose the best answer: View the Exhibit and examine the structure of the CUSTOMERS table. ...
- 【CF453D】 Little Pony and Elements of Harmony(FWT)
题面 传送门 设\(a\)的递推公式为 \[a_i=\sum_ja_jb[count(i\oplus j)]\] 其中\(\oplus\)为异或,\(count(i)\)表示\(i\)的二进制中\(1 ...
- 2016级算法第五次上机-F.ModricWang的水系法术
1066 ModricWang的水系法术 思路 比较典型的最大流问题,需要注意的是,题目已经暗示(明示)了这里的边是双向的,在建图的时候需要加上反向边的容量值. 解决最大流问题的基本思路就是不断在残量 ...