label标签和argument方法重载以及eval函数(详解)

本文详细介绍了HTML `<label>`标签的for属性及其使用,强调了为label添加for属性能提升用户体验的原因。此外,讲解了JavaScript中的`arguments`对象在方法重载中的应用,以及`eval()`函数的工作原理和潜在风险,提醒开发者尽量避免不必要的`eval()`使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<label>标签及for属性

Label对象
表示一个HTML<keygen>元素

访问Label对象
使用getElementById()来访问<label>元素
var x=document.getElementById("myLabel");

创建Label对象
var x=document.createElement("LABEL");

Label对象属性
control  描述:返回标注的控件
form     描述:返回一个包含Label的表单的引用
htmlFor  描述:设置或返回label的for属性的值

label的for属性总结
1.定义:for属性规定label与哪个表单元素绑定。
<label>是专门为<input>元素服务的,为其定义标记;

label和表单控件绑定方式有两种:
方法一:将表单控件作为label的内容,这种就是隐士绑定
此时,不需要for属性,绑定的控件也不需要id属性
隐士绑定:
<label>Date of Birth:<input type="text" name="DofB" /></label>

方法二:为label标签下的for属性命名一个目标表单的id,这种就是显示绑定。
显式绑定:
<label for="SSN">Social Security Number:</label>
<input type="text" name="SocSecNum" id="SSN" />

二、为什么要给label上面加上for属性
给 label 加了 for 属性绑定了input控件后,可以提高鼠标用户的用户体检。
如果在label 元素内点击文本,就会触发此控件,也就是说,当用户渲染该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。

Label htmlFor 属性
返回 label 的 for 属性的值:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>

<form>
<label id="myLabel" for="male">Male</label>
<input type="radio" name="sex" id="male" value="male"><br>
</form>
<p>点击“尝试一下”按钮返回 label 的 for 属性的值。</p>
<p id="demo"></p>
<button οnclick="myFunction()">尝试一下</button>
<script>
function myFunction(){
    var x = document.getElementById("myLabel").htmlFor;
    document.getElementById("demo").innerHTML=x;
}
</script>

</body>
</html>

定义和用法
htmlFor 属性设置或返回 lable 的 for 属性的值。
for 属性指定 label 要绑定到哪一个表单元素。
语法
返回 htmlFor 属性:
labelObject.htmlFor
设置 htmlFor 属性:
labelObject.htmlFor=id
属性值
id     label 要绑定的元素的 id。
技术细节
返回值: 字符串,表示 label 要绑定的元素的 id。

二 argument方法重载

1. parameter是指函数定义中参数,而argument指的是函数调用时的实际参数。
2. 简略描述为:parameter=形参(formal parameter), argument=实参(actual parameter)。
3. 在不很严格的情况下,现在二者可以混用,一般用argument,而parameter则比较少用。

<form>
        <h2>方法重载</h2>
        <input type="button" value="计算平方" οnclick="myMethod(12)" />
        <input type="button" value="计算加法" οnclick="myMethod(12,45)" />
        </form>
    </body>
    <script type="text/javascript">
        function myMethod(){
            if(arguments.length==1){
                //计算平方
                var n=parseInt(arguments[0]);
                alert(n+" 的平方为:"+n*n);
            }else if(arguments.length==2){
                //计算和
                var n=parseInt(arguments[0]);
                var m=parseInt(arguments[1]);
                var result=n+m;
                alert(n+"与"+m+"的和为:"+result);
            }
        }
    </script>

三 eval函数

语法
eval(string)

参数
string
    一个表示 JavaScript 表达式、语句或一系列语句的字符串。表达式可以包含变量与已存在对象的属性。

返回值
返回字符串中代码的返回值。如果返回值为空,则返回 undefined。

描述
eval() 是全局对象的一个函数属性。
eval() 的参数是一个字符串。如果字符串表示的是表达式,eval() 会对表达式进行求值。如果参数表示一个或多个 JavaScript 语句,那么eval() 就会执行这些语句。注意不要用 eval() 来执行一个算术表达式:因为 JavaScript可以自动为算术表达式求值。如果你以字符串的形式构造算术表达式,则可以用 eval() 在随后对其求值。

例如,假设你有一个变量 x,您可以通过将表达式的字符串值(例如 3 * x +2)赋值给一个变量,然后在你的代码后面的其他地方调用 eval(),来推迟涉及 x 的表达式的求值。

如果 eval() 的参数不是字符串, eval() 会将参数原封不动地返回。在下面的例子中,String 构造器被指定,而 eval() 返回String 对象而不是执行字符串。

eval(new String("2 + 2")); // 返回了包含"2 + 2"的字符串对象
eval("2 + 2");             // returns 4

你可以使用一些通用的方法来绕过这个限制,例如使用 toString()。

var expression = new String("2 + 2");
eval(expression.toString());

如果你间接的使用 eval(),比如通过一个引用来调用它,而不是直接的调用eval。 从 ECMAScript 5 起,它工作在全局作用域下,而不是局部作用域中。

这就意味着,例如,下面的代码的作用声明创建一个全局函数,并且 eval 中的这些代码在执行期间不能在被调用的作用域中访问局部变量。

function test() {
  var x = 2, y = 4;
  console.log(eval('x + y'));  // 直接调用,使用本地作用域,结果是 6
  var geval = eval; // 等价于在全局作用域调用
  console.log(geval('x + y')); // 间接调用,使用全局作用域,throws

ReferenceError 因为`x`未定义
  (0, eval)('x + y'); // 另一个间接调用的例子
​}

避免在不必要的情况下使用 eval!
eval() 是一个危险的函数, 它使用与调用者相同的权限执行代码。如果你用eval() 运行的字符串代码被恶意方(不怀好意的人)修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。更重要的是,第三方代码可以看到某一个 eval() 被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的 Function 就不容易被攻击。

eval() 通常比其他替代方法更慢,因为它必须调用 JS 解释器,而许多其他结构则可被现代 JS 引擎进行优化。
Bad code with eval:
function looseJsonParse(obj){
    return eval(obj);
}
console.log(looseJsonParse(
   "{a:(4-1), b:function(){}, c:new Date()}"
))

Better code without eval:

function looseJsonParse(obj){
    return Function('"use strict";return (' + obj + ')')();
}
console.log(looseJsonParse(
   "{a:(4-1), b:function(){}, c:new Date()}"
))

 
function Date(n){
    return

["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunda

y"][n%7 || 0];
}
function looseJsonParse(obj){
    return eval(obj);
}
console.log(looseJsonParse(
   "{a:(4-1), b:function(){}, c:new Date()}"
))


function Date(n){
    return

["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunda

y"][n%7 || 0];
}
function runCodeWithDateFunction(obj){
    return Function('"use strict";return (' + obj + ')')()(
        Date
    );
}
console.log(runCodeWithDateFunction(
   "function(Date){ return Date(5) }"
))

 
console.log(Function('"use strict";return(function(a){return a

(5)})')()(function(a){
return"Monday Tuesday Wednesday Thursday Friday Saturday

Sunday".split(" ")[a%7||0]}));

There are also additional safer (and faster!) alternatives to eval()

or Function() for common use-cases.

访问成员属性

你不应该去使用 eval() 来将属性名字转化为属性。考虑下面的这个例子,被访问对象的属性在它被执行之前都会未知的。这里可以用 eval 处理:

var obj = { a: 20, b: 30 };
var propName = getPropName(); // 返回 "a" 或 "b"

eval( 'var result = obj.' + propsName )

但是,这里并不是必须得使用 eval() 。事实上,这里并不建议这样使用。可以使用 属性访问器 进行代替,它更快、更安全:

var obj = { a: 20, b: 30 }
var propName = getPropName(); // 返回 "a" 或 "b"
var result = obj[ propName ]; // obj[ "a" ] 与 obj.a 等价

你还可以使用这个方法去访问子代的属性。如下:

var obj = {a: {b: {c: 0}}};
var propPath = getPropPath(); // 例如返回 "a.b.c"

eval( 'var result = obj.' + propPath )

这里,可以通过分割属性路径、循环遍历不同的属性,来避免 eval():

function getDescendantProp(obj, desc) {
  var arr = desc.split('.');
  while (arr.length) {
    obj = obj[arr.shift()];
  }
  return obj;
}

var obj = {a: {b: {c: 0}}};
var propPath = getPropPath(); // 例如返回 "a.b.c"
var result = getDescendantProp(obj, propPath);

同样的方法也可实现设置子代的属性值:

function setDescendantProp(obj, desc, value) {
  var arr = desc.split('.');
  while (arr.length > 1) {
    obj = obj[arr.shift()];
  }
  return obj[arr[0]] = value;
}

var obj = {a: {b: {c: 0}}};
var propPath = getPropPath();  // 例如,返回 "a.b.c"
var result = setDescendantProp(obj, propPath, 1);  // a.b.c 值为 1

使用函数而非代码段

JavaScript 拥有 first-class functions,这意味着你可以将函数直接作为参数传递给其他接口,将他们保存在变量中或者对象的属性中,等等。很多DOM的API都用这种思路进行设计,你也可以(或者应该)这样子设计你的代码:

// 代替 setTimeout(" ... ", 1000) 写法:
setTimeout(function() { ... }, 1000);

// 代替 elt.setAttribute("onclick", "...") 写法:
elt.addEventListener('click', function() { ... } , false);

闭包 也有助于创建参数化函数而不用连接字符串。
解析 JSON(将字符串转化为 JavaScript 对象)

如果你在调用 eval() 传入的字符串参数中包含数据(如:一个数组“[1,2,3]”)而不是代码,你应该考虑将其转换为 JSON 对象,这允许你用JavaScript语法的子集来表示数据。在扩展中下载JSON和JavaScript提示:因为 JSON 语法子集相对于 JavaScript 语法子集比较有局限性,很多在 JavaScript 中可用的特性在 JSON 中就不起作用了。比如,后缀逗号在JSON 中不支持,并且对象中的属性名在 JSON 中必须用引号括起来。请务必使用 JSON 序列化方法来生成稍后将被解析为 JSON 的字符串。
尽量传递数据而非代码

例如,设计为抓取网页内容的扩展,可能会在XPath中定义抓取规则,而不是在JavaScript 代码中。
以有限权限运行代码

如果你必须执行这段代码, 应考虑以更低的权限运行。此建议主要适用于扩展和 XUL 应用程序,可以使Components.utils.evalInSandbox 做到降低权限

使用 eval

在下面的代码中,两种包含了 eval() 的声明都返回了 42。第一种是对字符串"x + y + 1" 求值;第二种是对字符串 "42" 求值。

var x = 2;
var y = 39;
var z = "42";
eval("x + y + 1"); // returns 42
eval(z);           // returns 42

使用 eval 执行一串 JavaScript 语句下面的例子使用 eval() 来执行 str 字符串。这个字符串包含了如果 x 等于5,就打开一个Alert 对话框并对 z 赋值 42,否则就对 z 赋值 0 的JavaScript 语句。 当第二个声明被执行,eval() 将会令字符串被执行,并最终返回赋值给 z 的 42。

var x = 5;
var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z =

0;";
console.log('z is ', eval(str));

如果您定义了多个值,则会返回最后一个值。

var x = 5;
var str = "if (x == 5) {console.log('z is 42'); z = 42; x = 420; }

else z = 0;";
console.log('x is ', eval(str)); // z is 42  x is 420

返回值

eval 返回最后一个表达式的值。

var str = 'if ( a ) { 1 + 1; } else { 1 + 2; }';
var a = true;
var b = eval(str);  // returns 2
console.log('b is : ' + b);
a = false;
b = eval(str);  // returns 3
console.log('b is : ' + b);

eval 中函数作为字符串被定义需要“(”和“)”作为前缀和后缀
var fctStr1 = 'function a() {}'
var fctStr2 = '(function a() {})'
var fct1 = eval(fctStr1)  // return undefined
var fct2 = eval(fctStr2)  // return a function

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值