关闭

JavaScript中的行为委托

时间: 2018-09-03阅读: 1107标签: js知识

什么是行为委托?

简单来说就是一种设计模式,不同于传统的构造函数的“类”式设计。


在这之前先说一下原型的基本知识。
什么是原型?简单来说就是一个对象内部关联另外一个对象,本质来说就是对象与对象之间的关联;
一个对象本身没有属性或者方法会到原型对象上查找。

这里每个例子会通过构造函数,class和行为委托来不同实现,不过不会评论class,是否使用class取决于你的观点。


先看一个例子,构造函数写法

function Foo(name) {
    this.name = name;
}
Foo.prototype.age = function() {
    console.log(this.name);
};
function Fn(name) {
    Foo.call(this);
    this.name = name;
}
Fn.prototype = Object.create(Foo.prototype);
Fn.prototype.constructor = Fn.prototype;
Fn.prototype.set = function(value) {
    this.name = value;
};
var a1 = new Fn('zhangsan');
a1.age(); //zhangsan
var a2 = new Fn('lisi');
a2.set('xiaowu'); 
a2.age(); //xiaowu


class写法

class Foo {
    constructor(name) {
    this.name = name;
    }
    age() {
        console.log(this.name);
    }
}
class Fn extends Foo {
    constructor(name) {
        super();
        this.name = name;
    }
    set(value) {
        this.name = value;
    }
}
var a1 = new Fn('zhangsan');
a1.age(); //zhangsan
var a2 = new Fn('lisi');
a2.set('xiaowu'); 
a2.age(); //xiaowu


行为委托写法

var Foo = {
        const(name) {
            this.name = name;
    },
    age() {
        console.log(this.name);
    }
};
var Fn = Object.create(Foo);
Fn.set = function (value) {
    this.name = value;
};
var a1 = Object.create(Fn);
a1.const('zhangsan');
a1.age(); //zhangsan
var a2 = Object.create(Fn);
a2.set('xiaowu'); 
a2.age(); //xiaowu


可以看到比起构造函数,行为委托是通过原型链来实现的,他值关心一件事情,对象指向的关系。

再来看一个复杂一些的例子,为dom添加样式。

function Foo(value) {
    this.dom = value;
}
Foo.prototype.div = function () {
    var div = document.createElement(this.dom);
    this._dom = document.body.appendChild(div);
    return this._dom;
};
Foo.prototype.get = function () {
    return this._dom;
};
function Fn(text, cssText) {
    Foo.call(this, 'div');
    this.text = text;
    this.cssText = cssText;
}
Fn.prototype = Object.create(Foo.prototype);
Fn.prototype.constructor = Fn.prototype;
    Fn.prototype.set = function () {
    this.div();
    var div = this.get();
    div.textContent = this.text;
    Object.keys(this.cssText).forEach((name) => {
        div.style.cssText += `${name}: ${this.cssText[name]}`;
    });
};
var a = new Fn('hi', {color: 'red', "font-size": '16px'});
a.set();


class写法

class Foo {
    constructor(value) {
        this.dom = value;
    }
    div() {
        var div = document.createElement(this.dom);
        this._dom = document.body.appendChild(div);
    return this._dom;
    }
    get() {
        return this._dom;
    }
}
class Fn extends Foo {
    constructor(text, cssText) {
    super('div');
    this.text = text;
    this.cssText = cssText;
}
set() {
    super.div();
    var div = super.get();
    div.textContent = this.text;
    Object.keys(this.cssText).forEach((name) => {
        div.style.cssText += `${name}: ${this.cssText[name]}`;
    });
}
}
var a = new Fn('hi', { color: 'red', "font-size": '16px' });
a.set();


  

行为委托写法

var Foo = {
        const(value) {
        this.dom = value;
},
    div() {
        var div = document.createElement(this.dom);
        this._dom = document.body.appendChild(div);
        return this._dom;
},
    get() {
        return this._dom;
    }
};
var Fn = Object.create(Foo);
Fn.constructor = function (text, cssText) {
    this.const.call(this, 'div');
    this.text = text;
    this.cssText = cssText;
};
Fn.set = function () {
    this.div();
    let div = this.get();
    div.textContent = this.text;
    Object.keys(this.cssText).forEach((name) => {
        div.style.cssText += `${name}: ${this.cssText[name]}`;
    });
};
var a = Object.create(Fn);
a.constructor('hi', { color: 'red', "font-size": '16px' });
a.set();


 

注意点:
1.在使用行为委托时要避免标识符的重名,因为行为委托是基于原型链,不同于“类”的设计模式,可以构造函数与实例对象同时定义相同的名称的标识符。

2.两个委托对象无法互相委托,假设一个a对象关联b对象,然后b对象再关联a对象,如果两个引用了一个两个对象都不存在的属性或者方法,那么就会在原型链上形成无限循环。

来源:https://www.cnblogs.com/boses/p/9575247.html

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/1045

关闭

javascript不可变性是什么?

不可变性即某个变量在进行了某个操作之后,其本身没有发生变化,比如对于字符串而言,对字符串的任何操作都会改变字符串本身的值,而是在字符串的基础上复制出来一个然后再改变,这样我们就说是不可变的

你不知道的 js 保留字

先是笼统的说一下有什么保留字,保留字的话根据犀牛书的划分,可有分为以下几类:基础保留字、严格模式下的保留字、严格模式下的不完全保留字、ECMAScript3的保留字、ECMAScipt 5 的保留字、全局变量和函数

js词法作用域和作用域的理解_什么是javascript词法作用域?

JavaScript引擎在代码执行前会对其进行编译:第一步编译阶段,第二步运行阶段。词法作用域:定义在词法阶段的作用域,即书写代码时函数声明的位置决定的。词法分析器处理代码时会保持作用域不变

await在forEach不起作用解决

我们知道await这个机制肯定是没问题的,如果真的有问题肯定不会轮到我测出来,那么其实剩下来的问题只能是for遍历的原因了。lodash的forEach和[].forEach不支持await,如果非要一边遍历一边执行await,可使用for-of

js设备判断_判断移动端还是PC端?判断android还是ios?判断移动端浏览器类型?

js判断用户的浏览设备是移动设备还是PC?判断详细浏览器设备信息。判断微信、新浪、QQ打开。判断是android系统还是ios系统...

归并排序JavaScript实现_关于归并排序思路和代码实现

归并排序:其基本思想是分治策略,先进行划分,然后再进行合并,步骤是: 1.我们以数组[1, 5, 6, 2, 4, 3]举例,归并排序的第一步,将数组一分为2;2.接着将分成的数组继续一分为2,直到长度为1,我们构成如下二叉树(成树 从上往下)

基于规则评分的密码强度检测算法分析及实现(JavaScript)

用正则表达式做用户密码强度的通过性判定,过于简单粗暴,不但用户体验差,而且用户帐号安全性也差。那么如何准确评价用户密码的强度,保护用户帐号安全呢?本文分析介绍了几种基于规则评分的密码强度检测算法

JavaScript中的魔幻代理Proxy

什么是 JavaScript 代理?通过 Proxy 我们可以拦截并改变一个对象的几乎所有的根本操作,包括但不限于属性查找、赋值、枚举、函数调用等等。利用 Proxy,我们可以拦截并不存在的属性的读取

Js中的命名空间(namespace)

全局变量应该由有系统范围相关性的对象们保留,并且它们的命名应该避免含糊并尽量减少命名冲突的风险。在实践中,这意味着你应该避免创建全局对象,除非它们是绝对必须的。 所以你对此是怎么做的?传统方法告诉我们,最好的消除全局策略是创建少数作为潜在模块和子系统的实际命名空间的全局对象。

原生js实现控制函数执行次数/频率

在开发中,遇到需求如下:当函数function fn(){//...}执行的次数超过设定值后,将执行另一个函数fn2。实现方式如下

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!