• JS的面向对象与原型


     原型

    const yoshi = { skulk: true };
    const hattori = { sneak: true };
    const kuma = { creep: true }; ⇽--- 创建3个带有属性的对象
    assert("skulk" in yoshi, "Yoshi can skulk");
    assert(!("sneak" in yoshi)), "Yoshi cannot sneak");
    assert(!("creep" in yoshi)), "Yoshi cannot creep"); ⇽--- yoshi对象只能访问自身的属性skulk
    Object.setPrototypeOf(yoshi, hattori); ⇽--- Object. setProto-typeOf方法, 将对象hattori设置为yoshi对象的原型
    assert("sneak" in yoshi, "Yoshi can now sneak"); ⇽--- 通过将hattori对象设置为yoshi对象的原型, 现在yoshi可以访问hattori对象的属性
    assert(!("creep" in hattori)), "Hattori cannot creep"); ⇽--- 目前hattori对象还不具有属性creep
    Object.setPrototypeOf(hattori, kuma); ⇽--- 将kuma对象设置为hattori对象的原型
    assert("creep" in hattori, "Hattori can now creep"); ⇽--- 现在hattori对象可以访问属性creep
    assert("creep" in yoshi, "Yoshi can also creep"); ⇽--- 通过将hattori对象设置为yoshi对象的原型, 现在yoshi对象也可以访问属性creep

     对象构造器与原型

    function Ninja(){} ⇽--- 定义一个空函数, 什么也不做, 也没有返回值
    Ninja.prototype.swingSword = function(){
    return true;
    }; ⇽--- 每个函数都具有内置的原型对象, 我们可以对其自由更改
    const ninja1 = Ninja();
    assert(ninja1 === undefined , "No instance of Ninja created."); ⇽--- 作为函数调用Ninja, 验证该函数没有任何返回值
    const ninja2 = new Ninja();
    assert(ninja2 && ninja2.swingSword && ninja2.swingSword(),"Instance exists and method is callable." ); ⇽--- 作为构造函数调用Ninja, 验证不仅创建了新的实例, 并且该实例具有原型上的方法

    每个函数都有一个原型对象, 该原型对象将被自动设置为通过该函数创建对象的原型。

    关于实例属性与原型属性

    function Ninja(){
    this.swung = false; ⇽--- 创建布尔类型的实例变量, 并初始化该变量的默认值为false
    this.swingSword = function(){
    return !this.swung; ⇽--- 创建实例方法, 该方法的返回值为实例变量swung取反
    };
    Ninja.prototype.swingSword
    = function(){ return this.swung; }; ⇽--- 定义一个与实例方法同名的原型方法, 将会优先使用哪一个呢 const ninja = new Ninja(); assert(ninja.swingSword(),"Called the instance method, not the prototype met};

    通过原型一切都可以在运行时进行修改

    function Ninja(){
    this.swung = true;
    } ⇽--- 定义了一个构造函数, 该构造函数中创建了一个swung属性, 初始化为布尔值
    const ninja1 = new Ninja(); ⇽--- 通过new操作符调用构造函数, 创建实例Ninja
    Ninja.prototype.swingSword = function(){
    return this.swung;
    }; ⇽--- 在实例对象创建完成之后, 在原型上添加一个方法
    assert(ninja1.swingSword(), "Method exists, even out of order."); ⇽--- 验证该方法存在于对象中
    Ninja.prototype
    = { pierce: function() { return true; } } ⇽--- 使用字面量对象完全重写Ninja的原型对象, 仅有一个pierce方法 assert(ninja1.swingSword(),"Our ninja can still swing!"); ⇽--- 尽管我们已经完全替换了Ninja的构造器原型, 但是实例化后的Ninja对象仍然具有swingSword方法, 因为对象ninja1仍然保持着对旧的Ninja原型的引用 const ninja2 = new Ninja(); assert(ninja2.pierce(),"Newly created ninjas can pierce"); assert(!ninja2.swingSword, "But they cannot swing!"); ⇽--- 新创建的ninja2实例拥有新原型的引用, 因此不具有swingSword方法, 仅具有pierce方法
  • 相关阅读:
    log4j使用教程
    (POI)Excel格式转Html格式
    log4j2使用教程
    Spring AOP 面向切面编程入门
    C# 标准事件模式
    1Angular的MVC和作用域
    3Angular的模块化
    2Angular的双向数据绑定(MVVM)
    5手动初始化Angular的模块与控制器
    python读取 UCS2 little endian(utf16le) 格式的文件
  • 原文地址:https://www.cnblogs.com/wiggin-Z/p/11320783.html
Copyright © 2020-2023  润新知