- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
众所周知,要声明多个变量,可以使用如下格式:
let k = 0,
j = 5 /*etc....*/
return
关键字),还使用逗号“,”运算符,如下所示:
let r = "hello there world, how are you?"
.split("")
.map(x => (x+=5000, x.split("").map(
y => y+ + 8
).join("")))
.join("")
console.log(r)
let k = 0, console.log(k), k += 8
Uncaught SyntaxError: Unexpected token '.'
let k = 0, k += 8
Uncaught SyntaxError: Identifier 'k' has already been declared
(let k = 0, k += 8);
Uncaught SyntaxError: Unexpected identifier
(k = 0, k += 8);
function meval(mainStr, argList) {
let ID = (
Math.random().toString() +
performance.now().toString()
).split(".").join("").split("")
.map(x => ("qwertyuio")[x])
.join(""),
varName = "$______"+ID+"_____$",
str = `
var ${varName} = {};
(argList => {
Object.entries(argList).forEach(x => {
${varName}[x[0]] = x[1];
})
});
`;
let myEval = eval;
return (() => {
myEval(str)(argList)
myEval(`
${
Object.keys(argList).map(x =>
"let " + x + " = " + varName + "['" + x +"'];"
).join("\n")
}
${mainStr}
delete window[${varName}];
`)
})()
}
meval(`
var g = a.ko + " world!"
`, {
a: {ko: "hi"}
})
console.log(g);
最佳答案
你不能这样做。变量声明语法允许使用逗号来一次声明多个变量。每个变量也可以可选地初始化为声明的一部分,因此语法(更抽象):
(var | let | const) variable1 [= value1], variable2 [= value2], variable3 [= value3], ..., variableN [= valueN]
但是,这不是
comma operator。就像
parseInt("42", 10)
中的逗号也不是逗号运算符一样-只是逗号字符在不同的上下文中具有不同的含义。
2 + 2
,
fn()
,
a ? b : c
等。这是将要计算并产生东西的东西。
2 + fn()
或
( a ? ( 2 + 2 ) : ( fn() ) )
(为清晰起见,每个表达式都用方括号括起来)。即使表达式不会产生不会改变任何事情的可用值-没有显式返回的函数也会产生
undefined
,因此
2 + noReturnFn()
将产生乱码,但它仍然是有效的表达式语法。
a = 1
将产生要赋值的值:
let foo;
console.log(foo = "bar")
undefined
就是什么。示例包括
if(cond){}
,
return result
和
switch
。
if (return 7)
一样嵌套它们,因为这在语法上无效。您还不能在需要表达式的地方使用语句-
console.log(return 7)
同样无效。
console.log("the console.log call itself is an expression statement")
console.log(let foo = "bar"); //invalid - statement instead of expression
exp1, exp2, exp3, ..., expN
并接受表达式,而不是语句。它一个接一个地执行它们并返回最后一个值。由于语句没有返回值,因此它们在这种情况下永远无效:
(2 + 2, if(7) {})
从编译器/解释器的 Angular 来看是无意义的代码,因为此处无法返回任何内容。
let a = 1, a += 1
不起作用,因为逗号被视为变量声明语句,并且如果我们尝试执行
( ( let a = 1 ), ( a += 1 ) )
,该语句仍然无效,因为第一部分仍然是语句,而不是表达式。
const fn = x => {
let k = computeValueFrom(x);
doSomething1(k);
doSomething2(k);
console.log(k);
return k;
}
因此,它是一个产生值并在少数地方使用它的函数。我们将尝试将其转换为速记语法。
const fn = x => (k => (doSomething1(k), doSomething2(k), console.log(k), k))
(computeValueFrom(x));
fn(42);
在自己的内部声明一个新函数,该函数将
k
作为参数,然后立即使用
computeValueFrom(x)
的值调用该函数。如果为了清楚起见,将函数与调用分开,则会得到:
const extractedFunction = k => (
doSomething1(k),
doSomething2(k),
console.log(k),
k
);
const fn = x => extractedFunction(computeValueFrom(x));
fn(42);
因此,该函数获取
k
并与逗号运算符依次使用几次。我们只调用该函数并提供
k
的值。
const fn = (fn, k) => (
k = computeValueFrom(x),
doSomething1(k),
doSomething2(k),
console.log(k),
k
);
fn(42);
与以前基本相同-我们使用逗号运算符执行多个表达式。但是,这一次我们没有额外的功能,我们只是向
fn
添加了额外的参数。参数是局部变量,因此在创建局部可变绑定(bind)方面,它们的行为类似于
let
/
var
。然后,我们将其分配给该
k
标识符,而不会影响全局范围。这是我们第一个表达方式,然后我们继续其余的表达方式。
fn(42, "foo")
,第二个参数也将被覆盖,因此实际上它与
fn
仅采用单个参数的情况相同。
const fn = x => { let k = computeValueFrom(x); doSomething1(k); doSomething2(k); console.log(k); return k; }
fn(42);
我撒了谎。或更确切地说,我作弊。这不是在表达式上下文中,您拥有与以前相同的一切,但是只是删除了换行符。重要的是要记住,您可以执行此操作,并用分号分隔不同的语句。它仍然是一行,并且几乎没有更长的时间。
const log = x => {
console.log(x);
return x;
}
const fn = compose(computeValueFrom, doSomething1, doSomething2, log)
fn(42);
这是一个巨大的话题,所以我在这里几乎不涉及任何问题。我也大大简化了事情,只是为了介绍这个概念。
if
,
for
并调用多个函数/方法来产生效果。
itemsToBuy
.filter(item => item.stockAmount !== 0) // remove sold out
.map(item => item.price * item.basketAmount) // get prices
.map(price => price + 12.50) // add shipping tax
.reduce((a, b) => a + b, 0) // get the total
数组支持来自函数世界的方法,因此这是一个有效的FP示例。
const getPrice = item => item.price * item.basketAmount;
const addShippingTax = price => price + 12.50;
但是您实际上并不需要执行两个映射操作。我们可以将它们重写为:
const getPriceWithShippingTax = item => (item.price * item.basketAmount) + 12.50;
但是让我们尝试这样做而不直接修改功能。我们可以一个接一个地称呼它们,这将起作用:
const getPriceWithShippingTax = item => addShippingTax(getPrice(item));
现在,我们已经重用了这些功能。我们将调用
getPrice
,并将结果传递给
addShippingTax
。只要我们调用的下一个函数使用上一个函数的输入,此方法就起作用。但这并不是很好-如果我们要同时调用
f
,
g
和
h
这三个函数,则需要
x => h(g(f(x)))
。
const compose = (...functions) => input => functions.reduce(
(acc, fn) => fn(acc),
input
)
const f = x => x + 1;
const g = x => x * 2;
const h = x => x + 3;
//create a new function that calls f -> g -> h
const composed = compose(f, g, h);
const x = 42
console.log(composed(x));
//call f -> g -> h directly
console.log(h(g(f(x))));
const composed = x => {
const temp1 = f(x);
const temp2 = g(temp1);
const temp3 = h(temp2);
return temp3;
}
但支持任何数量的功能,并且不使用临时变量。因此,我们可以归纳出许多可以有效执行相同操作的过程-从一个函数传递一些输入,获取输出并将其馈送到下一个函数,然后重复执行。
doSomething1
和doSomething2
需要返回它们获得的值。我已经包含了log
来显示需要发生的事情-取一个值,对其进行处理,然后返回该值。我只是想提出这个概念,所以我只用了最短的代码就可以做到这一点。 compose
可能是误称。它有所不同,但是通过许多实现,compose
通过参数向后工作。因此,如果您要调用f
-> g
-> h
,则实际上是compose(h, g, f)
。这样做是有道理的-真正的版本毕竟是h(g(f(x)))
,因此compose
是模拟的。但是,它的阅读效果不是很好。我显示的从左到右的组合通常被命名为pipe
(如Ramda)或flow
(如Lodash)。我认为将compose
用于功能组合标题会更好,但是您阅读compose
的方式起初是违反直觉的,因此我从左至右进行了翻译。 eval
邓,邓,邓!
const fn2 = x => (eval(`var k = ${computeValueFrom(x)}`), doSomething1(k), doSomething2(k), console.log(k), k)
fn(42);
所以...我又撒了谎。您可能会想:“老兄,如果这全都是谎言,我为什么要用这个人写给我的人”。如果您正在考虑-很好,请继续考虑。不要使用它,因为它是
super 坏。
eval
动态创建本地绑定(bind)。然后用表示绑定(bind)。这不会创建全局变量:
const f = x => (eval(`var y = ${x} + 1`), y);
console.log(f(42)); // 42
console.log(window.y); // undefined
console.log("y" in window); // false
console.log(y); // error
var
而不是
let
或
const
?这只是您可以自己入门的第一步。使用
var
的原因是,当使用
eval
或
let
进行调用时,
const
始终会创建一个新的词汇环境。您可以看到规格
chapter 18.2.1.1 Runtime Semantics: PerformEval。由于
let
和
const
仅在封闭的词法环境中可用,因此您只能在
eval
内部而不是外部访问它们。
eval("const a = 1; console.log('inside eval'); console.log('a:', a)");
console.log("outside eval");
console.log("a: ", a); //error
var
,以便声明在
eval
之外可用。
eval
时必须非常小心,因为您正在生成代码。我使用数字作弊(...一如既往)。数字文字和数字值是相同的。但是,如果没有数字,则会发生以下情况:
const f = (x) => (eval("var a = " + x), a);
const number = f(42);
console.log(number, typeof number); //still a number
const numericString = f("42");
console.log(numericString, typeof numericString); //converted to number
const nonNumericString = f("abc"); //error
console.log(nonNumericString, typeof nonNumericString);
numericString
生成的代码是
var a = 42;
-这是字符串的值。因此,它被转换。然后使用
nonNumericString
会出错,因为它会生成
var a = abc
,并且没有
abc
变量。
const f = (x) => (eval(`var a = "${x}"`), a);
const numericString = f("42");
console.log(numericString, typeof numericString); //still a string
const nonNumericString = f("abc"); //no error
console.log(nonNumericString, typeof nonNumericString); //a string
const number = f(42);
console.log(number, typeof number); //converted to string
const undef = f(undefined);
console.log(undef, typeof undef); //converted to string
const nul = f(null);
console.log(nul, typeof nul); //converted to string
var a = "null"
与
null
不同。
eval
。而且
JSON.stringify
不会剪切它,因为它不能完美地序列化对象-例如,它将删除(或更改)
undefined
值,函数,并且在保留原型(prototype)或圆形结构时会失败。
eval
代码无法由编译器优化,因此它比仅创建绑定(bind)要慢得多。如果您不确定会是这种情况,那么您可能没有单击规范的链接。现在就做。
eval
涉及多少东西?每个规范有29个步骤,其中多个步骤引用了其他抽象操作。是的,有些是有条件的,是的,步骤的数量并不一定意味着要花费更多的时间,但是它肯定比创建绑定(bind)需要做更多的工作。提醒,引擎无法即时优化,因此您将比“真实”(非
eval
ed)源代码要慢。
eval
。是的,
eval
可以安全使用
eval("2 + 2")
不会产生任何副作用或问题。问题是您必须绝对确定要向
eval
提供已知的良好代码。那么,对
eval("2 + " + x)
的分析将是什么?在追溯所有可能的
x
设置路径之前,我们无法确定。然后回溯用于设置
x
的所有内容。然后追溯那些,等等,直到您发现初始值是安全的还是不安全的。如果它来自不受信任的地方,那么您有问题。
x
中。假设您有一个
example.com?myParam=42
,所以您从查询字符串中获取
myParam
的值。攻击者可以轻易地制作一个查询字符串,将其
myParam
设置为可窃取用户凭据或专有信息并将其发送给自己的代码。因此,您需要确保您正在过滤
myParam
的值。但是,您还必须经常进行相同的分析-如果您引入了新事物,现在又从cookie中获取
x
的值,该怎么办?好吧,现在这很脆弱。
x
的每个可能值都是安全的,您也不能跳过重新运行分析的过程。而且您必须定期执行此操作,然后在最佳情况下,只需说“确定就可以了”。但是,您可能还需要证明这一点。您可能只需要为
x
填满一天。如果您又使用过
eval
四次,则需要整整一周的时间。
关于javascript - JavaScript声明一个变量并在一个语句中使用逗号运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61077989/
我有一个 html 格式的表单: 我需要得到 JavaScript在value input 字段执行,但只能通过表单的 submit .原因是页面是一个模板所以我不控制它(不能有
我管理的论坛是托管软件,因此我无法访问源代码,我只能向页面添加 JavaScript 来实现我需要完成的任务。 我正在尝试用超链接替换所有页面上某些文本关键字的第一个实例。我还根据国家/地区代码对这些
我正在使用 JS 打开新页面并将 HTML 代码写入其中,但是当我尝试使用 document.write() 在新页面中编写 JS 时功能不起作用。显然,一旦看到 ,主 JS 就会关闭。用于即将打开的
提问不是为了解决问题,提问是为了更好地理解系统 专家!我知道每当你将 javascript 代码输入 javascript 引擎时,它会立即由 javascript 引擎执行。由于没有看过Engi
我在一个文件夹中有两个 javascript 文件。我想将一个变量的 javascript 文件传递到另一个。我应该使用什么程序? 最佳答案 window.postMessage用于跨文档消息。使
我有一个练习,我需要输入两个输入并检查它们是否都等于一个。 如果是 console.log 正则 console.log false 我试过这样的事情: function isPositive(fir
我正在做一个Web应用程序,计划允许其他网站(客户端)在其页面上嵌入以下javascript: 我的网络应用程序位于 http://example.org 。 我不能假设客户端网站的页面有 JQue
目前我正在使用三个外部 JS 文件。 我喜欢将所有三个 JS 文件合而为一。 尽一切可能。我创建 aio.js 并在 aio.js 中 src="https://code.jquery.com/
我有例如像这样的数组: var myArray = []; var item1 = { start: '08:00', end: '09:30' } var item2 = {
所以我正在制作一个 Chrome 扩展,它使用我制作的一些 TamperMonkey 脚本。我想要一个“主”javascript 文件,您可以在其中包含并执行其他脚本。我很擅长使用以下行将其他 jav
我有 A、B html 和 A、B javascript 文件。 并且,如何将 A JavaScript 中使用的全局变量直接移动到 B JavaScript 中? 示例 JavaScript) va
我需要将以下整个代码放入名为 activate.js 的 JavaScript 中。你能告诉我怎么做吗? var int = new int({ seconds: 30, mark
我已经为我的 .net Web 应用程序创建了母版页 EXAMPLE1.Master。他们的 I 将值存储在 JavaScript 变量中。我想在另一个 JS 文件中检索该变量。 示例1.大师:-
是否有任何库可以用来转换这样的代码: function () { var a = 1; } 像这样的代码: function () { var a = 1; } 在我的浏览器中。因为我在 Gi
我收到语法缺失 ) 错误 $(document).ready(function changeText() { var p = document.getElementById('bidp
我正在制作进度条。它有一个标签。我想调整某个脚本完成的标签。在找到可能的解决方案的一些答案后,我想出了以下脚本。第一个启动并按预期工作。然而,第二个却没有。它出什么问题了?代码如下: HTML:
这里有一个很简单的问题,我简单的头脑无法回答:为什么我在外部库中加载时,下面的匿名和onload函数没有运行?我错过了一些非常非常基本的东西。 Library.js 只有一行:console.log(
我知道 javascript 是一种客户端语言,但如果实际代码中嵌入的 javascript 代码以某种方式与在控制台上运行的代码不同,我会尝试找到答案。让我用一个例子来解释它: 我想创建一个像 Mi
我如何将这个内联 javascript 更改为 Unobtrusive JavaScript? 谢谢! 感谢您的回答,但它不起作用。我的代码是: PHP js文件 document.getElem
我正在寻找将简单的 JavaScript 对象“转储”到动态生成的 JavaScript 源代码中的最优雅的方法。 目的:假设我们有 node.js 服务器生成 HTML。我们在服务器端有一个对象x。
我是一名优秀的程序员,十分优秀!