如何使 property/method 可调用或不可调用?
How to make a property/method invokable or not?
我想实现这个功能:
- 我有一个对象
var obj = {};
我在那个对象上有三个属性,obj.zero
& obj.one
& obj.binaryString
obj.zero
& obj.one
是方法,而 obj.binaryString
是字符串
当我链接属性时,我希望它们将各自的数字添加到 binaryString
。例如:
obj.one.zero.zero.one
=> 使 obj.binaryString
= 1001
obj.one.zero.one.one.zero
=> 使 obj.binaryString
= 10110
我已经通过这个实现了上述功能:
function Binary () {
var obj = { binaryString: '' };
Object.defineProperty(obj, 'zero', {
get: function() {
obj.binaryString += '0';
return obj;
}
});
Object.defineProperty(obj, 'one', {
get: function() {
obj.binaryString += '1';
return obj;
}
});
return obj;
}
var binary = new Binary();
binary.one.zero.zero.one // => obj.binaryString becomes '1001'
现在我想注销已完成的 binaryString
,以及我使用以下代码完成的 additionalString
:
// placed inside Binary constructor function
Object.defineProperty(obj, 'log', {
get: function() {
return function(additionalString) {
console.log(obj.binaryString + additionalString);
};
}
});
所以使用当前代码我可以这样做:
binary.one.zero.one.zero.one.log(' is the answer');
// logs out `10101 is the answer`
我想做的是摆脱 log
并使 one
和 zero
方法可调用或不可调用,这样我就可以实现此功能:
binary.one.one.zero.one(' is the result')
// => logs out `1101 is the result`
我该怎么做?
我相信它的功能与 Chalk 的工作方式类似:
chalk.blue.bold('Hello world!');
// `blue` is not invoked here but it adds the color blue to the style
chalk.blue('Hello world!');
// `blue` IS invoked here. It adds blue to the style and returns the stylized string
只需将对象设为函数,然后打印任何你想要的。
function Binary () {
var obj = function(msg){ console.log(msg+this.binaryString ) };
obj.binaryString = ''
Object.defineProperty(obj, 'zero', {
get: function() {
obj.binaryString += '0';
return obj;
}
});
Object.defineProperty(obj, 'one', {
get: function() {
obj.binaryString += '1';
return obj;
}
});
return obj;
}
var binary = new Binary();
binary.one.zero.zero.one.zero(" is the result ")
我想指出,您正在做的事情是一个非常 bad/dangerous 的想法:滥用读取属性来改变对象本身是自找麻烦。您现在可能看不到它,但它会以难以发现的错误和令人费解的模式的形式导致痛苦和心痛。
你可以做的是,这不是那么危险,而不是改变对象本身,return一个Binary
的新实例每次调用 #one
或 #zero
。例如:
function Binary(s) {
this.binaryString = s || ''
}
Object.defineProperty(Binary.prototype, 'zero', {
get: function() {
return new Binary(this.binaryString + '0')
}})
Object.defineProperty(Binary.prototype, 'one', {
get: function() {
return new Binary(this.binaryString + '1')
}})
这是 Chalk 采用的方法,会更安全,更不容易出错。
更新:
在考虑了您的问题并看到了您的问题之后,我认为最好的方法是完全不使用 类。您可以使用纯基于函数的方法解决此问题。它是不可变的,它是安全的,而且我相信它不那么令人困惑。在 ES5 中:
function bin(str) {
if(!str) str = ''
function f(msg) { return str + ' ' + msg }
return Object.defineProperties(f, {
zero: {
get: function() {
return bin(str + '0')
},
},
one: {
get: function() {
return bin(str + '1')
},
},
})
}
如果你可以使用 ES6(又名 ES2015),你可以让它更紧凑:
function bin(str = '') {
return Object.defineProperties(msg => `${str} ${msg}`, {
zero: { get() { return bin(str + '0') } },
one: { get() { return bin(str + '1') } },
})
}
你会像这样使用它:
bin().one.zero.one.zero('is the answer') // '1010 is the answer'
我想实现这个功能:
- 我有一个对象
var obj = {};
我在那个对象上有三个属性,
obj.zero
&obj.one
&obj.binaryString
obj.zero
&obj.one
是方法,而obj.binaryString
是字符串
当我链接属性时,我希望它们将各自的数字添加到 binaryString
。例如:
obj.one.zero.zero.one
=> 使 obj.binaryString
= 1001
obj.one.zero.one.one.zero
=> 使 obj.binaryString
= 10110
我已经通过这个实现了上述功能:
function Binary () {
var obj = { binaryString: '' };
Object.defineProperty(obj, 'zero', {
get: function() {
obj.binaryString += '0';
return obj;
}
});
Object.defineProperty(obj, 'one', {
get: function() {
obj.binaryString += '1';
return obj;
}
});
return obj;
}
var binary = new Binary();
binary.one.zero.zero.one // => obj.binaryString becomes '1001'
现在我想注销已完成的 binaryString
,以及我使用以下代码完成的 additionalString
:
// placed inside Binary constructor function
Object.defineProperty(obj, 'log', {
get: function() {
return function(additionalString) {
console.log(obj.binaryString + additionalString);
};
}
});
所以使用当前代码我可以这样做:
binary.one.zero.one.zero.one.log(' is the answer');
// logs out `10101 is the answer`
我想做的是摆脱 log
并使 one
和 zero
方法可调用或不可调用,这样我就可以实现此功能:
binary.one.one.zero.one(' is the result')
// => logs out `1101 is the result`
我该怎么做?
我相信它的功能与 Chalk 的工作方式类似:
chalk.blue.bold('Hello world!');
// `blue` is not invoked here but it adds the color blue to the style
chalk.blue('Hello world!');
// `blue` IS invoked here. It adds blue to the style and returns the stylized string
只需将对象设为函数,然后打印任何你想要的。
function Binary () {
var obj = function(msg){ console.log(msg+this.binaryString ) };
obj.binaryString = ''
Object.defineProperty(obj, 'zero', {
get: function() {
obj.binaryString += '0';
return obj;
}
});
Object.defineProperty(obj, 'one', {
get: function() {
obj.binaryString += '1';
return obj;
}
});
return obj;
}
var binary = new Binary();
binary.one.zero.zero.one.zero(" is the result ")
我想指出,您正在做的事情是一个非常 bad/dangerous 的想法:滥用读取属性来改变对象本身是自找麻烦。您现在可能看不到它,但它会以难以发现的错误和令人费解的模式的形式导致痛苦和心痛。
你可以做的是,这不是那么危险,而不是改变对象本身,return一个Binary
的新实例每次调用 #one
或 #zero
。例如:
function Binary(s) {
this.binaryString = s || ''
}
Object.defineProperty(Binary.prototype, 'zero', {
get: function() {
return new Binary(this.binaryString + '0')
}})
Object.defineProperty(Binary.prototype, 'one', {
get: function() {
return new Binary(this.binaryString + '1')
}})
这是 Chalk 采用的方法,会更安全,更不容易出错。
更新:
在考虑了您的问题并看到了您的问题之后,我认为最好的方法是完全不使用 类。您可以使用纯基于函数的方法解决此问题。它是不可变的,它是安全的,而且我相信它不那么令人困惑。在 ES5 中:
function bin(str) {
if(!str) str = ''
function f(msg) { return str + ' ' + msg }
return Object.defineProperties(f, {
zero: {
get: function() {
return bin(str + '0')
},
},
one: {
get: function() {
return bin(str + '1')
},
},
})
}
如果你可以使用 ES6(又名 ES2015),你可以让它更紧凑:
function bin(str = '') {
return Object.defineProperties(msg => `${str} ${msg}`, {
zero: { get() { return bin(str + '0') } },
one: { get() { return bin(str + '1') } },
})
}
你会像这样使用它:
bin().one.zero.one.zero('is the answer') // '1010 is the answer'