一切都是对象!

  以下的四种(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原型与继承的更多相关文章

  1. 【面试必备】javascript的原型和继承

    原型.闭包.作用域等知识可以说是js中面试必考的东西,通过你理解的深度也就能衡量出你基本功是否扎实.今天来复习一下javascript的原型和继承,虽说是老生常谈的话题,但对于这些知识,自己亲手写一遍 ...

  2. 深入浅出JavaScript之原型链&继承

    Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instanc ...

  3. javascript的原型和继承(1)

    原型与继承是javascript中基础,重要而相对比较晦涩难解的内容.在图灵的网上看到一篇翻译过的文章,有参考了一些知名博客.我自己总结了几篇.通过这次的总结,感觉自己对原型和继承的认识又增加了很多, ...

  4. JavaScript的原型链继承__propt__、prototype、constructor的理解、以及他们之间相互的关系。

    回想自己已经工作了有一段时间了,但是自己对JavaScript的原型链.和继承的理解能力没有到位,最近他们彻底的整理并且复习了一遍. 本案例中部分文案来自网络和书籍,如有侵权请联系我,我只是把我的理解 ...

  5. JavaScript 面向对象 原型(prototype) 继承

    1.对象的概念:无需属性的集合,属性可以为数值,对象或函数,ECMAscript中没有类的概念,这点是javascript与其他面向对象(OO)语言不同的地方. //创建一个自定义对象 var per ...

  6. JavaScript基于原型的继承

    在一个纯粹的原型模式中,我们会摒弃类,转而专注于对象,基于原型的继承相比基于类的继承的概念上更为简单 if( typeof Object.beget !== 'function') { Object. ...

  7. javascript的原型与继承(2)

    这是上一篇的后续. Javascript是一种基于对象的语言,遇到的所有东西几乎都是对象.如果我们想要把属性和方法封装成一个对象,应该怎么做呢: 假设我们把猫看成一个对象: var Cat = { n ...

  8. javascript高级:原型与继承

    原型继承的本质就是一条原型链,对象会沿着这条链,访问链里的方法属性. 对象的__proto__属性就是用于访问它的原型链的上一层: 考虑以下对象: 1. 所有对象的原型: Object.prototy ...

  9. 🍓JavaScript 对象原型链继承的弊端 🍓

  10. javascript中继承(一)-----原型链继承的个人理解

    [寒暄]好久没有更新博客了,说来话长,因为我下定决心要从一个后台程序员转为Front End,其间走过了一段漫长而艰辛的时光,今天跟大家分享下自己对javascript中原型链继承的理解. 总的说来, ...

随机推荐

  1. LVM与RAID阵列

    创建LVM分区: 相关命令: pvcreat /dev/sdb{1,2,3} 创建物理卷 vgcreat test_vg1 /dev/sdb1 创建卷组     vgcreat test_vg2 -s ...

  2. Arcgis Android 坐标转换

    http://spatialreference.org/首先,在上面的网站查出现有的坐标srid,然后查出目标Srid. 参考api 示例代码 Point point = new Point(120. ...

  3. WPF 简洁的主界面

    用的是dev的TileLayouotControl控件. <dxwui:PageAdornerControl Header="" Padding="30" ...

  4. oracle goldengate的两种用法

    此文已由作者赵欣授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 自从oracle收购来了goldengate这款产品并以后对它做了一系列改进后,有非常多的用户使用它做数据迁移 ...

  5. git subrepo

    此文已由作者张磊授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 前言 目前对 git 仓库拆分的已有实现之一,并没有合并到 git 发行版中.项目的地址是 https://g ...

  6. django 保存订单乐观锁的使用

    后端在生成订单表的时候,牵扯到如下的知识点: 1 事物 2 高并发 3 时间函数的使用 一,事务: from django.db import transaction save_id = transa ...

  7. BeginEditorCommand的原理

    代码来源 :http://www.arch-pub.com/problem-about-CPropertyPage_10682271.html CWnd* pAcadWnd = CWnd::FromH ...

  8. [Flex] 修改注释中的@author方法

    当然,在Flash Builder里,按Ctrl+Shift+D可以很方便在添加AsDoc注释,也可以修改,可是有些生成的@author是系统的用户名(如:administor),如何修改 修改方法之 ...

  9. MVC软件设计模式

    Model(模型):负责数据维护 View(视图):负责向用户呈现数据 Control(控制):负责模型和视图之间的交互 应用:Struts就是基于MVC模式的架构

  10. TX2之多线程读取视频及深度学习推理

    背景 一般在TX2上部署深度学习模型时,都是读取摄像头视频或传入视频文件进行推理,从视频中抽取帧进行目标检测等任务.对于大点的模型,推理的速度是赶不上摄像头或视频的帧率的,如果我们使用单线程进行处理, ...