【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:

  如果继承得到的方法感觉不合适,你可以自己进行修改。

  如果继承无法满足需要,还可以自己添加方法。不过如果你要添加内置方法的原型属性,最好做一步判断,如果该属性不存在,则添加。如果本来就存在,就没必要再添加了。

时间: 2024-08-25 13:10:11

【Javascript】Javascript原型与继承的相关文章

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

Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承. 这部分知识也是JavaScript里的核心重点之一,同时也是一个难点.我把学习笔记整理了一下,方便大家学习,同时自己也加深印象.这部分代码的细节很多,需要反复推敲.那我们就开始吧. 小试身手 原型链

JavaScript基于原型的继承

在一个纯粹的原型模式中,我们会摒弃类,转而专注于对象,基于原型的继承相比基于类的继承的概念上更为简单 if( typeof Object.beget !== 'function') { Object.beget = function(o) { var F = function() {}; F.prototype = o; return new F(); } } var myMammal = { name : 'Herb the Mammal', get_name : function() { r

JavaScript的原型与继承

首先,什么是原型: JavaScript里所有函数,变量方法都是对象,而对象对应的就是原型(prototype). 所以以此来看,JS里任何的对象都有一个原型对象,而默认的原型对象就处在原型链的最顶端. 现在说到了一个新的概念,什么是原型链? 在JavaScript中,一共有两种类型的值,原始值和对象值.每个对象都有一个内部属性[[prototype]],我们通常称之为原型.原型的值可以是一个对象,也可以是null.如果它的值是一个对象,则这个对象也一定有自己的原型.这样就形成了一条线性的链,我

JavaScript中原型与继承(简单例子)

利用原型prototype创建自定义对象Person: function Person(name,sex){ this.name = name; this.sex = sex; } Person.prototype = { getName:function(){return this.name}, getSex:function(){return this.sex} } var liu = new Person("lcy","female"); //创建一个空白对象

JavaScript教程——对象的继承

面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承.传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现,本章介绍 JavaScript 的原型链继承. ES6 引入了 class 语法,基于 class 的继承不在这个教程介绍,请参阅<ES6 标准入门>一书的相关章节. 原型对

JavaScript之基础-16 JavaScript 原型与继承

一.JavaScript 原型 原型的概念 - 在JavaScript中,函数本身也是一个包含了方法和属性的对象 - 每个函数中都有一个prototype属性,该属性引用的就是原型对象 - 原型对象是保存共享属性值和共享方法的对象 为对象扩展属性 - 扩展单个对象的成员 - 扩展共享的属性值 - 内存图描述 删除属性 - 可以使用delete关键字删除对象的属性 自由属性与原型属性 - 自有属性:通过对象的引用添加的属性;其它对象可能无此属性;即使有,也是彼此独立的属性 emp1.job = '

对Javascript的原型,原型链和继承的个人理解

继承是OO语言中一个最为人津津乐道的概念,也是初接触Javascript的初学者难理解的概念=.=继承主要分为两种:一种是接口继承,另一种是实现继承.而在ECMAScript中只支持实现继承,所以我们今天来讨论讨论实现继承.实现继承就是继承实际的方法,主要依靠原型链来实现.讲到这里我们就需要讨论讨论什么是原型链. 1.什么是原型 要理解原型链我们首先要知道什么是原型.我们知道每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,这个对象包含所有实例共享的属性和方法.所以我个人

javascript原型链继承

一.关于javascript原型的基本概念: prototype属性:每个函数都一个prototype属性,这个属性指向函数的原型对象.原型对象主要用于共享实例中所包含的的属性和方法. constructor属性:每个原型对象都有一个constructor属性,这个constructor属性包含一个指向prototype属性所在函数的指针. 例如 Foo.prototype.constructor指向Foo函数.这个属性是只读的. __proto__属性(ES6通过对__proto__属性进行标

JavaScript面向对象原型继承

<script type="text/javascript"> //原型链继承 function shape() { this.name="shape"; this.showname=function(){ console.log(this.name); } } function shape_Two() { this.name='shape_Two' } function Triangle(side,height) { this.name="T

JavaScript构造函数+原型创建对象,原型链+借用构造函数模式继承父类练习

虽然经常说是做前端开发的,但常常使用的技术反而是JQuery比较多一点.在JavaScript的使用上相对而言少些.尤其是在创建对象使用原型链继承上面,在项目开发中很少用到.所以今天做个demo练习一下,以后忘记了也可以照搬一下. 说明一下: 1. Demo中使用的是构造函数+原型模式创建的对象.构造函数中存储对象实例使用的属性,原型模式增加实例使用的方法. 2. Demo中的继承分为两个方面.一个是属性继承,使用的是借用构造函数模式 call()方法.另一个是方法继承,这个就是使用原型方式继承