【问题标题】:Object's Property Activates Function When Changed?对象的属性在更改时激活功能?
【发布时间】:2013-05-31 11:32:47
【问题描述】:

我有一个对象,在这个例子中是法拉利。例如,当使用ferrari.speed = 90; 更改速度时,我希望此属性对更改执行一些操作,例如使用函数更改屏幕上法拉利的速度。

我想知道最简单、最不疯狂的方法是什么?

这是一个 jsfiddle:

http://jsfiddle.net/qhV7B/3/

<button id="addspeed">speed up!!</button>
<button id="checkspeed">Check the speed!</button>


function car(){
    speed: 0;
    //Do something about speed change here? if its changed at all, greater or smaller?
}
document.getElementById('addspeed').onclick = function speedchange(){
    ferrari.speed++;
}
document.getElementById('checkspeed').onclick = function checkspeed() {
    alert(ferrari.speed);
}
var ferrari = new car();
ferrari.speed = 10;

【问题讨论】:

  • 使用函数代替,即ferrari.setSpeed(90),您可以执行任何其他必要的函数。
  • @asawyer 我有点想使用传统方法。 ferrari.speed = 90;
  • @lawm 在这种情况下,我不知道您所说的“传统方法”是什么意思。你想要for this property to do something about the change 对吗?你打算如何用一个简单的字段来完成这个?
  • 那是……呃……问题!我将速度设置为无功能,当发生这种情况时,会触发一个功能。

标签: javascript oop object properties


【解决方案1】:

Set operator 就是你要找的https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/set

这是我的解决方案http://jsfiddle.net/qhV7B/6/

function car(){
}

car.prototype = {
    hidden_speed: 0,
    set speed(v){
        //special action
        alert("I changed value to " + v);
        this.hidden_speed = v;
    },
    get speed(v){
        return this.hidden_speed;
    },
};

var ferrari = new car();
ferrari.speed = 10;

document.getElementById('addspeed').onclick = function speedchange(){
    ferrari.speed = (ferrari.speed + 1);
}
document.getElementById('checkspeed').onclick = function checkspeed() {
    alert(ferrari.speed);
}

【讨论】:

  • 这个解决方案更干净,虽然取决于目标浏览器它不会工作 - 来自 Mozilla 的文档:No support (notably in IE6-8) means that the script will trigger a syntax error.
  • Object.defineProperty 也是如此:一种可能的解决方案,但并未在所有主要浏览器上实现。这就是为什么人们仍然坚持使用ferrari.setSpeed() 解决方案的原因。
  • 嗯...谁在乎 IE
  • 我的反对意见更实际——从维护的角度来看,它使代码更难阅读和理解。从调用代码中看到的函数调用很清楚,看到一个字段集,您将无法知道可能会发生什么副作用。这是一个虫巢。
  • 问题是,我不会一次性使用它。这将是一个图书馆,让它动态对我来说很重要。
【解决方案2】:

可以通过 getter 和 setter 完成,一种方法是通过 Object.defineProperty():

function car(){
    this._speed=0;
}
...
var ferrari = new car();
Object.defineProperty(car.prototype,"speed",{
    get:function(){return this._speed;},
    set:function(v){
        this._speed=v;
        document.getElementById("speed").textContent=v.toString(10);
    }
});
ferrari.speed = 10;

修改fiddlefiddle

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

其他关于 getter 和 setter 的文档可能会或可能不会过时和/或依赖于平台:

* 编辑:将Object.defineProperty 的参数从ferrari 更改为car.prototype

【讨论】:

  • 这对我来说真的不起作用,因为我正在寻找可以与汽车对象本身一起使用的东西,而不是专门用于法拉利的东西。就像,我可以拥有一百万辆不同的汽车。不过还是谢谢!
  • @lawm 在这种情况下更改为Object.defineProperty(car.prototype,...);。和another fiddle
【解决方案3】:

此代码使用setSpeed 方法,允许您在速度变化时添加所需的任何其他逻辑:

http://jsfiddle.net/rujbX/2/

var Car, ferrari,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

Car = (function() {
  function Car() {
    this.setSpeed = __bind(this.setSpeed, this);
  }

  Car.prototype.speed = 0;

  Car.prototype.setSpeed = function(newSpeed) {
    this.speed = newSpeed;
    //Here is where you custom logic needs to run
    return alert("Speed Changed to: " + this.speed);
  };

  return Car;

})();

ferrari = new Car();

ferrari.setSpeed(10);

document.getElementById('addspeed').onclick = function speedchange(){
    ferrari.setSpeed(ferrari.speed+1);
}
document.getElementById('checkspeed').onclick = function checkspeed() {
    alert(ferrari.speed);
}

The Javascript was generated here

【讨论】:

  • 就像我在埃文的回答中所说的那样,我希望通过设置实际属性来设置法拉利的速度,而不是使用函数。不过谢谢!
【解决方案4】:

使用 cmets 中的 asawyers 建议,您可以创建一个 speedUp 函数,该函数可以在更改时触发您的动画功能(或者如果您希望能够减速,则可以使用 speedChange,无论您的船漂浮在哪里)。

查看小提琴:http://jsfiddle.net/86HtX/

我还在那里对您的代码进行了一些调整:

function car(){
    var car = this;

    this.speed = 0;

    this.speedUp = function(mph){
         car.speed += mph;
         car.animate();
    };

    this.animate = function(){
         alert(car.speed); // new speed
    };

    //Do something about speed change here? if its changed at all, greater or smaller?
}

document.getElementById('addspeed').onclick = function speedchange(){
    ferrari.speedUp(1); // go 1 mph faster
}

document.getElementById('checkspeed').onclick = function checkspeed() {
    alert(ferrari.speed);
}

var ferrari = new car();
ferrari.speed = 10;

【讨论】:

  • 我希望使用ferrari.speed = 10; 与对象进行交互。然后会检测到...您的方法使用了一个函数,但是绕过了这一点。如果我在代码中使用ferrari.speed = 11,你的情况就不会发生任何事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
  • 2018-07-25
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多