将with语句与上下文一起使用是一个好主意吗?

时间:2016-02-18 09:11:12

标签: javascript html5 canvas with-statement

例如,如果我在游戏中有渲染功能,则以相当高的速率调用(由requestAnimationFrame确定),例如:

function render() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    ctx.beginPath();
    ctx.arc(player.x, player.y, player.size / 2, 0, Math.PI * 2);
    ctx.fillStyle = "#6f00ff";
    ctx.fill();
}

为什么不简单地将它全部包含在with-statement中?

function render() {
    with (ctx) {
        clearRect(0, 0, canvas.width, canvas.height);

        beginPath();
        arc(player.x, player.y, player.size / 2, 0, Math.PI * 2);
        fillStyle = "#6f00ff";
        fill();
    }
}

这是一个好主意/实践吗?如果没有,为什么不呢?

编辑///////

对于那些不知道HTML5画布是什么的人:

canvas是对<canvas> DOM(文档对象模型)元素的引用,可能如下所示:

var canvas = document.getElementsByTagName("canvas")[0];

和ctx是对:

的引用
var ctx = canvas.getContext("2d");

2 个答案:

答案 0 :(得分:1)

它通常不被认为是一个好主意,因为在代码中它是不明显的,如果:

canvas.width = ctx.canvas.width ?
player.x = ctx.player.x ?

此外,如果您将ctx定义为:

,该怎么办?
var ctx = {
    clearRect: function(){/* some code */},
    beginPath: function(){/* some code */},
    arc: function(){/* some code */},
    fill: function(){/* some code */},
}

然后当你这样做:

with (ctx) {
    fillStyle = "#6f00ff";
}

期待设置ctx.fillStyle,但它没有。相反,它只是设置一个全局变量fillStyle

因为它使可读性变差,with通常被认为是一个错误的功能,并且总是被避免。

答案 1 :(得分:1)

使用with根本不是一个好主意,事实上你不应该使用它。它在少数情况下很有用,而你的不是那些极少数情况之一:)

在MDN页面上描述了专家反对

<强>亲

  

Pro: with语句可以减少重复冗长对象引用的需要,从而减少文件大小,而不会降低性能。 'with'所要求的范围链变化在计算上并不昂贵。使用'with'将解释解释重复对象引用的解释器。但请注意,在许多情况下,可以通过使用临时变量来存储对所需对象的引用来实现此优势。

<强>反向

  

Contra: with语句强制首先搜索指定的对象以查找所有名称。因此,在'with'块中将找到不是指定对象成员的所有标识符。在性能很重要的情况下,“with”应仅用于包含访问指定对象成员的代码块。

基本上,他们所说的只要你正确地使用with()构造就可以了,但是如果你错过了一把钥匙就会慢得多。发生这种情况的可能性可能为0%,但如果您的程序中存在错误 - 这可能会导致错误并导致您在调试时遇到的错误。

<强> TL; DR;

除非您确切知道自己在做什么并且不使用ecmascript 5严格模式,否则请不要使用with();,因为它比安全构造更具风险权衡。