【问题标题】:Is it a good idea, to use the with-statement with the context? [closed]在上下文中使用 with 语句是个好主意吗? [关闭]
【发布时间】:2016-05-30 08:42:05
【问题描述】:

例如,如果我的游戏中有一个渲染函数,它会以相当高的速率(由 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 语句中?

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");

【问题讨论】:

    标签: javascript html canvas with-statement


    【解决方案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 通常被认为是一个有缺陷的功能并且总是被避免。

    【讨论】:

    • 什么?很明显ctx对象是CanvasRenderingContext2D的一个实例,更明显的是包含player属性
    • @Murplyx——这对每个人来说都不是显而易见的,对于那些可能需要维护代码的人来说可能不是。
    • @Murplyx:CanvasRenderingContext2D 对象没有player 属性真的很明显吗?如果库被更新为包含 player 属性并且添加它的人忘记了 with 声明怎么办?正是出于这个原因,with 被视为诱杀装置,在严格模式下被禁用。
    • 我进行了编辑以使其更清晰
    • 为什么“某人”会更新它以使其包含播放器属性?
    【解决方案2】:

    使用with 根本不是一个好主意,事实上你不应该使用它。它在少数情况下很有用,而您的情况并非如此有限:)

    在 MDN 页面上,描述了 procontra

    专业版

    优点: with 语句可以通过减少重复冗长对象引用的需要来帮助减小文件大小而不会降低性能。 'with' 所需的范围链更改在计算上并不昂贵。使用“with”将减轻解释器解析重复对象引用的负担。但是请注意,在许多情况下,可以通过使用临时变量来存储对所需对象的引用来实现此好处。

    反对

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

    基本上,他们的意思是,只要您正确使用with() 构造,您会没事的,但如果您错过一个键,它会慢得多。发生这种情况的可能性可能为 0%,但如果您的程序中存在错误 - 这可能会抓住它并导致您在调试时很难找到错误。

    TL;DR;

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

    【讨论】:

      猜你喜欢
      • 2019-08-24
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      • 2018-08-17
      • 2010-11-27
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多