草庐IT

说说js的原型链及继承那些事

甚时跃马归来 2023-03-28 原文

一:原型链

先说三个js原型链通用规则

1、每个对象都有__proto__属性,指向它的构造函数的prototype(不过这个__proto__由兼容性问题,在IE11以前用不了)
2、每个函数都有一个prototype属性
3、函数也是对象

先验证第一第二个规则

function Person(){}
Person.prototype.age = 12;
let justin = new Person();
console.log(justin.__proto__ === Person.prototype); // true
console.log(justin.age);//12

原型链

所谓原型链,也就是,查找对象的属性或方法时会从
对象本身 => 对象的构造函数.prototype =>
构造函数的(父)构造函数.prototype(如果中间有继承的话) =>...=>
Object.prototype => null

在上面的代码中查找age的时候,原型链是清晰且简单的,也就是
justin => Person.prototype => Object.prototype => null

因为justin上,没有age属性,age属性是在Person.prototype上的,

justin.__proto__ === Person.prototype,所以

justin => Person.prototype(justin.__proto__) 这一步是没有问题
那我们来验证一下,Person.prototype => Object.prototype 这一步

function Person(){}
Person.prototype.age = 12;
let justin = new Person();
console.log(justin.__proto__ === Person.prototype); // true
console.log(justin.age);//12
// ---------- 以下是新加的内容-------------

// 我们知道justin.__proto__ === Person.prototype; // 全等号
console.log(jusin.name);// undefined;

Object.prototype.name = 'bob'; // 注意这里我们设置的是Object.prototype.name
console.log(justin.name);// bob

console.log(Person.prototype.__proto__ === Object.prototype);// true
console.log(Object.prototype.__proto__ === null); // 全等号

所以justin原型链的大致结构图如下,如果Person中间有继承其他类的话,则会在Object.prototype
和Person.prototype之间有相应的.prototype对象插入其中,具体不细说了。

justin原型链图片

justin原型链图片.png

__proto__兼容性

__proto__兼容.png

二:继承

js如何实现继承?我们修改一下上面的代码

/**
 * 第一种方法
 */
function Person(){}
Person.prototype.age = 1;
Person.prototype.boss = '王多鱼';
Person.prototype.sayHello = function(){
    console.log('hello');
}

function ZuAnRen(){}

ZuAnRen.prototype.sayHello = function(){
    console.log('wdnmd');
}

// 我们造一个祖安人
let za1 = new ZuAnRen();

// 如何让ZuAnRen继承Person呢?
// 目前za1的原型链是这样的:  za1 => ZuAnRen.prototype => Object.prototype => null
// 要让ZuAnRen继承Person,也就是在ZuAnRen.prototype => Object.prototype之间插入一个Person.prototype
// 而 ZuAnRen.prototype 也是个对象,所以也有__proto__属性
// 所以试试这样
ZuAnRen.prototype.__proto__ = Person.prototype;
console.log(za1.boss);// 王多鱼  说明我们成功了!
za1.sayHello(); // wdnmd

/**
 * 第二种方法(使用class和extends,不细说)
 */


三:详细扒拉function中的proto

由于function也是一个对象,所以也有一个__proto__对象

所以,像上面的Person.__proto__等于谁呢?

答案是 Function.prototype

因为function就是由Function创建的(这里注意,后面的Function首字母大写)

Function.__proto__呢?

答案还是Function.prototype


function Person(){
    
}

console.log(Person.__proto__ === Function.prototype); // true
console.log(Function.__proto__ === Function.prototype); // true

最后补全原型链一张图

原型链整体.png

有关说说js的原型链及继承那些事的更多相关文章

  1. ruby-on-rails - Rails 单表继承 : How to override the value written to the type field - 2

    在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型

  2. ruby-on-rails - 为什么 DataMapper 使用混合与继承? - 2

    所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass

  3. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  4. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

  5. ruby-on-rails - Ruby on Rails 单表继承(STI)和单元测试问题(使用 PostgreSQL) - 2

    我正在使用带有单个“帐户”表的STI模型来保存用户和技术人员的信息(即用户...8)错误:test_the_truth(用户测试):ActiveRecord::StatementInvalid:PGError:ERROR:关系“技术人员”不存在:从“技术人员”中删除...从本质上讲,标准框架不承认Technicians和Users表(或PostgreSQL称它们为“关系”)不存在,事实上,应该别名为Accounts。有什么想法吗?我对RoR比较陌生,不知道如何解决这个问题而又不完全删除STI。 最佳答案 原来问题是由于存在:./te

  6. ruby - 为什么 Ruby 模块继承不像类继承那样工作? - 2

    假设我有一个名为Flight的模块,其中包含类方法和实例方法。我可以使用include、extend或两者将其方法放入类中:classBatinclude会将Flight添加到Bat.ancestors,但extend不会。我的问题是,为什么模块与类不同?当我对Mammal进行子类化时,我总是同时获得类和实例方法。然而,当我混入一个模块时,我不能同时获得类和实例方法(除非我使用self.included钩子(Hook)或类似ActiveSupport::Concern的东西)。这种差异背后是否存在语言设计问题? 最佳答案 Modul

  7. ruby - 为什么 Object 在 Ruby 中既包含内核又继承它? - 2

    在Ruby(1.8.X)中为什么Object既继承了内核又包含了内核?仅仅继承还不够吗?irb(main):006:0>Object.ancestors=>[Object,Kernel]irb(main):005:0>Object.included_modules=>[Kernel]irb(main):011:0>Object.superclass=>nil请注意,在Ruby1.9中情况类似(但更简洁):irb(main):001:0>Object.ancestors=>[Object,Kernel,BasicObject]irb(main):002:0>Object.included

  8. node.js - 如何在 Travis CI 上的一个项目中运行 Node.js 和 Ruby 测试 - 2

    我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每

  9. Ruby 获取继承类 - 2

    我正在为Rails创建我的第一个插件。我对ruby​​还是很陌生,我想知道是否有可能获得继承类?例如,我正在尝试创建一个插件,在您不使用迁移时允许进行单元测试和功能测试。我要做的是初始化一个名为controller的类变量,以初始化为正在测试的Controller类型。如果我有一个基类ControllerTest:classControllerTest所以我目前坚持的是获取继承类的名称。这可能吗?如果没有,有没有人知道我可以如何着手实现它的另一种方式?提前致谢。 最佳答案 非常简单:使用“继承”回调。来自Class类的RDoc:in

  10. ruby-on-rails - 是吗? Rails 3 中的单表继承失败 - 2

    Object#is_a?在Rails3中以最奇怪的方式失败。我将单表继承设置如下(为简洁起见进行了简化):#resource.rbclassResource在我的Controller中,我有这个:defcreate@resource=Resource.findparams[:resource_id]logger.info'@resourceclass:'+@resource.class.namelogger.info'@resourcesuperclass:'+@resource.class.superclass.namelogger.info'@resourceis_a?(Video

随机推荐