gpt4 book ai didi

javascript - 在函数表达式(或函数声明)中添加方法

转载 作者:行者123 更新时间:2023-12-03 00:28:40 27 4
gpt4 key购买 nike

我想尽可能简单地向函数表达式添加一个方法。就我而言,我使用函数表达式,但函数声明也可以。由于函数是对象,我想这是可能的。 但是如何呢?

<小时/>

详细信息:

我想尽可能简单、直接地添加方法,所以我既不想使用构造函数,也不想使用继承。

以下代码将方法(setListener)添加到函数(secondsEvent),没有构造函数和继承,但不在匿名函数表达式中,我想以某种方式实现(参见评论):

function listener1 (date) {
console.log("listener1: " + date);
}

function listener2 (date) {
console.log("listener2: " + date);
}

var secondsEvent = function () {
//The following causes "listener is not defined" in firefox console
//listener: listener1,

//The following causes "function statement requires a name" in firefox console,
//and if I give the function a name, I get "secondsEvent.setListener is not a function".
//Thus I add the property after this function expression.
//setListener: function (newListener) {
// listener = newListener;
//},
secondsEvent.listener(new Date());
var timeout = setTimeout(secondsEvent, 1000);
}

// Thus the following 5 lines are needed.
secondsEvent.listener = listener1;
secondsEvent.setListener = function (newListener) {
secondsEvent.listener = newListener;
console.log("listener now " + secondsEvent.listener.name);
}

secondsEvent();
secondsEvent.setListener(listener2);

代码产生以下输出:

listener1: Fri Dec 28 2018 21:55:05 GMT+0100 (Central European Standard Time) 
listener now listener2
listener2: Fri Dec 28 2018 21:55:06 GMT+0100 (Central European Standard Time)
listener2: Fri Dec 28 2018 21:55:07 GMT+0100 (Central European Standard Time)
.....
<小时/>

更新:

最初,我使用 Douglas Crockford 的术语“函数文字”而不是函数表达式,但现在更新了标题和问题。

为了响应Teemu的建议,我尝试了以下代码:

function listener1 (date) {
console.log("listener1: "+date + "<br>");
}

function listener2 (date) {
console.log("listener2: "+date + "<br>");
}

var secondsEvent = function () {
secondsEvent.listener = listener1;
secondsEvent.setListener = function (newListener) {
secondsEvent.listener = newListener;
console.log("listener now " + secondsEvent.listener.name);
}
clearTimeout(secondsEvent.timeout);
secondsEvent.listener(new Date());
secondsEvent.timeout = setTimeout(secondsEvent, 1000);
};

secondsEvent();
secondsEvent.setListener(listener2);

但是,它的输出如下:

listener1: Sat Dec 29 2018 10:47:48 GMT+0100 (Central European Standard Time)<br> test.js:2:5
listener now listener2 test.js:27:2
listener1: Sat Dec 29 2018 10:47:49 GMT+0100 (Central European Standard Time)<br> test.js:2:5
listener1: Sat Dec 29 2018 10:47:50 GMT+0100 (Central European Standard Time)<br>

为了避免每次调用 secondsEvent 时设置属性 secondsEvent.listenersecondsEvent.setListener,我使用以下内容:

secondsEvent.listener = secondsEvent.listener || listener1;
secondsEvent.setListener = secondsEvent.setListener || function (newListener) {
secondsEvent.listener = newListener;
console.log("listener now " + secondsEvent.listener.name);
}

是否有更好的解决方案只设置一次属性?也许有一些 js 初始化习惯用法? (我知道将其从函数中取出将是另一种解决方案,但这导致了我想要避免的第一个解决方案,因为将属性定义包含在函数表达式(或函数声明,无论您使用哪种)中会更好),在使用之前。

最佳答案

你提到了“函数文字”,但 JavaScript 中没有这样的东西。我们确实谈到了function expression不过。

您可以考虑的一件事是使用Object.assign,它将允许对象(作为文字提供)合并到(函数)对象中:

function listener1 (date) {
console.log("listener1: "+date);
}

function listener2 (date) {
console.log("listener2: "+date);
}

var secondsEvent = Object.assign(function () {
clearTimeout(secondsEvent.timeout);
secondsEvent.listener(new Date());
secondsEvent.timeout = setTimeout(secondsEvent, 1000);
}, {
listener: listener1,
setListener(newListener) {
this.listener = newListener;
console.log("listener now " + this.listener.name);
}
});

secondsEvent();
secondsEvent.setListener(listener2);

传统替代方案

下面的内容不是您所要求的,但我无论如何都会提供它作为比较。

将行为和数据结合起来的更传统方法是从对象开始。这里我们不使用额外的属性来扩展函数;该函数成为具有以下属性的对象的方法:

function listener1 (date) {
console.log("listener1: "+date);
}

function listener2 (date) {
console.log("listener2: "+date);
}

var secondsEvent = {
listener: listener1,
start() {
clearTimeout(this.timeout);
this.listener(new Date());
this.timeout = setTimeout(() => this.start(), 1000);
},
setListener(newListener) {
this.listener = newListener;
console.log("listener now " + this.listener.name);
}
};

secondsEvent.start(); // secondsEvent is not a function. We call a method
secondsEvent.setListener(listener2);

虽然在这里您需要使用 .start() 调用该函数,但它的优点是它的外观和工作方式与大多数其他对象类似:此 API 的用户不会感到惊讶。

关于javascript - 在函数表达式(或函数声明)中添加方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53964233/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com