个人适合网站类型公司网站建设需要多少钱
目录
一、运算符(操作符)
赋值运算符
圆括号运算符
算术运算符
比较运算符
逻辑运算符
逗号运算符
条件运算符
位运算符
typeof操作符
void操作符
delete操作符
instanceof操作符
in操作符
二、条件语句
if语句
switch语句
三、循环语句
for循环
while循环
do/while循环
break和continue
四、with语句
一、运算符(操作符)
赋值运算符
赋值运算符优先级最低。赋值的顺序自右向左。等号是最简单的赋值运算符。
a = b = c = 0; //将三个变量都初始化为0
赋值运算符和关系运算符配合使用。
> (a = 1) == 1 //赋值运算符具有非常低的优先级,需要补充圆括号以保证正确的运算顺序
< true
Javascript提供了11个复合赋值运算符。复合赋值运算符先进行指定运算,再将结果值赋给自身(例如加等于,加任意数再赋给自身)。复合赋值运算只用来简化操作,并不会带来性能上的提升。
//常用的复合赋值运算符
> a += b ---> a = a + b
> a -= b ---> a = a - b
> a *= b ---> a = a * b
> a /= b ---> a = a / b
> a %= b ---> a = a % b //位操作,使用频率很低
> a <<= b ---> a = a << b
> a >>= b ---> a = a >> b
> a >>>= b ---> a = a >>> b
> a &= b ---> a = a & b
> a |= b ---> a = a | b
> a ^= b ---> a = a ^ b
圆括号运算符
圆括号运算符有两种用法,其一作为分组符号,其二作为执行符号。
圆括号作为分组符号(分组运算符)
分组符号可以用来控制表达式中的运算优先级。Javascript将分组符号中的内容当作表达式来解析,返回表达式的值或表达式本身。分组符号不能包含js语句(js语句不能被当作表达式解析),分组符号不能为空。
//返回表达式的值
> (1) ---> 1
> ('1') ---> '1'
> (1 + 2) ---> 3
//返回表达式本身
> var obj = {}
> (obj) ---> //返回对象本身> function f(){ }
> (f) ---> //返回函数本身
> ( var a = 1 ) // 报错,js语句不能被当作表达式解析
> (function(){}) // 分组符号将函数转换为表达式
圆括号作为执行符号
圆括号作为执行符号用来调用函数。执行符号必须放在表达式后面(函数名作为变量,是一种基本表达式),函数必须先转换为表达式才能被执行符号调用(函数声明后面跟执行符号会报错,因为函数声明不是表达式)。
> function a(){ }() //报错
> function b(){ }(1) //不报错,返回1
//函数声明后面加(1),仅仅相当于在声明语句之后又跟了一条毫无关系的表达式等价于
> function b(){ }
> (1)
算术运算符
算术运算符分为一元算术运算符和二元算术运算符两种。计算的顺序自左向右。
一元算术运算符
一元运算符作用于单个操作数,并返回一个新值。一元运算符具有很高的优先级,且都是右结合运算符(由右向左运算)。一元算术运算符包括一元正号(+)、一元负号(-)、自加(++)和自减(--)。
自加运算符自身加1再赋给自身,++位置不固定,放前面先自加再执行语句(前增量运算符),放后面先执行语句并返回结果再自加(后增量运算符),同理还有自减。
一元正号运算符和一元负号运算符放在表达式前面,隐式调用Number()将非数值类型转换为数值类型(类型转换后一元负号运算符将返回的数值转换为负数)。在new Date()前面使用一元正号运算符可以把日期字符串转换为日期毫秒数。
> + '1' // 1
> - '1' // -1
> +undefined // NaN
> new Date() //Mon Feb 18 2019 12:52:30 GMT+0800 (中国标准时间)
> +new Date() //1550465550486
> -new Date() //-1550465550486
二元算术运算符
二元算术运算符包括加(+)、减(-)、乘(*)、除(/)和求余(%)。二元算术运算符进行数值运算时隐式调用Number()将非数值类型转换为数值类型。加号有两个作用,其一进行数值运算,其二连接字符串(任意类型值加字符串都返回字符串类型)。求余运算符也叫求模运算符,返回第一个操作数除以第二个操作数的余数(返回结果与第一个操作数的符号保持一致)。被除数是Infinity或除数是0时求余结果为NaN。在Javascript中求余运算符允许将浮点数作为操作数,但得到的结果不准确。
console.log(7 % 3); // 1
console.log(7 % -3); // 1
console.log(-7 % 3); //-1
console.log(-7 % -3); //-1
> console.log(9.5 % 3.2);
< 3.0999999999999996
小练习
> var a = 10;
> var b = ++a - 1 + a++;
> b + ',' + a
< "21,12"
> var a = 2;
> var b = a-- -1;
< 1
> var a = (10 * 3 - 4 / 2 + 1) % 2, b = 3;
> b %= a + 3;
> console.log(a++)
> console.log(b--)
< 1
< 3
//交换a,b的值
> var a = 123,b = 234;
> a = a + b;
> b = a - b;
> a = a - b;
比较运算符
比较运算符也叫关系运算符。
基本比较运算符:大于、小于、等于、大于等于、小于等于、不等于
消除隐式转换的比较运算符:绝对等于、绝对不等于(比较过程没有任何类型转换)
//基本比较运算符: >、 <、 ==、 >=、 <=、!=
//消除隐式转换的比较运算符:===、!==
var a = 1 == 2; //false
var a = undefined == undefined; //true
var a = Infinity == Infinity ; //true
var a = NaN == NaN; //false 非数是唯一一个自己也不等于自己的
//字符串之间比较的是ASCII码
"10" > "9" // false, 从第一位开始逐位比较ASCII码, 相等则依次比较下一位, 不等则直接取比较结果 --> "1" < "9"
逻辑运算符
逻辑运算符有与、或、非三种。
与运算符
与运算符连接表达式形成短路语句。当前表达式为true则继续看后面的,为false则中断并返回当前表达式的值。与运算符形成的短路语句是if语句的一种简写形式。
> var a = 1 && 2; //相当于if(1){ a = 2 }
> a
< 2
var a = 1 && 2 + 2; //结果:4
var a = 1 + 1 && 1 - 1 //结果:0
var a = 1 && true && 0; //结果:0
或运算符
或运算符连接表达式形成短路语句。当前表达式为false则继续看后面的,为true则中断并返回当前表达式的值。
> var a = 1 || 2;
< 1
//或运算符可以写兼容
div.onclick = function(e){ var event = e;//非ievar event2 = window.event;//ievar event3 = e || window.event; // ie和非ie都可以
}
// e是一个事件对象
// 非ie浏览器里面,var event = e 就可以取到e的值,
// ie浏览器中e里面没东西,但是window.event里面存放着和e相同的内容
非运算符
把对象转换成布尔值并取反。undefined、null、NaN、""(空串)、0、false 六个对象转换的布尔值为false,其余所有转换的布尔值均为true。
> var a = !""
< true> var a = !123
< false> var a = !!""
< false> !function(){ return 0; }
< false> !function(){ return 0; }() //形成一个立即执行函数---> !0
< true
逗号运算符
逗号运算符可以将若干个表达式连接起来按顺序执行,并返回最右边表达式的值。它的优先级只比赋值运算符高。
> 1, 2, 3
< 3
逗号运算符用于赋值
> var a = (1, 2, 3); // a = 3 去掉括号会报错
> b = 1, 2, 3; // b = 3 不报错,因为没有关键字var
逗号运算符用于声明多个变量
> var a = 1,b = 1,c,d = [];
逗号运算符用于for循环
for语句的增量表达式只允许单个表达式被执行。逗号运算符允许将多个表达式视为单个表达式。
fo(var i = 0, j = 0;i < 3; i++, j++){ //i++,j++被当作一个表达式执行,且都会被单独执行console.log(i+j);
}
< 0
< 2
< 4
逗号运算符连接多个函数
> var a = ( function f(){ return "1"} , function g(){ return 2 } )();
> a
< 2
//结论:只执行函数g,不会执行函数f
//原因:先执行逗号表达式,返回函数g ---> (function g(){ })()
( (function f(){console.log(1);})() , (function g(){ console.log(2);})()
);
//函数f和g都会被执行
条件运算符
条件运算符是Javascript中唯一一个三目运算符(也叫三元运算符,有三个操作数,操作数是运算符作用的实体,是表达式的一部分)。条件运算符的操作数可以是任意类型的表达式。条件运算符的计算规则是将第一个操作数转换为布尔值,为true则计算第二个操作数并返回其计算结果,为false则计算第三个操作数并返回其结果。
var a = true ? 1 : 2; //a = 2;
var b = false ? 1 : 2; //b = 1;
var c = 1 > 0 ? (1 < 0 ? 3 : 3) : 2; //可以嵌套多个,小括号可以省略
条件运算符可以作为if else语句的一种简写形式。
if(a){//表达式1
}else{//表达式2
}a ? 表达式1 : 表达式2
位运算符
位运算符直接操作内存中的二进制比特位,是非常底层的运算,速度快但不直观。位运算符包含7种运算,分别是按位非(~)、按位与(&)、按位或(|)、按位异或(^)、左移(<<)、有符号右移(>>)和无符号右移(>>>)。
Javascript中数值以IEEE-754 64位格式存储。位运算符不直接操作64位数值,而是先将其转换为32位带符号整数(4个字节),然后执行位操作,最后再将32位的结果值转换为64位。特殊值NaN和Infinity值执行位操作时被当作0来处理。对非数值进行位操作时先使用Number()函数将其转换为数值类型后再执行,得到的结果为数值类型。位操作会忽略操作数的小数部分且返回值一定是整数。
32位带符号整数中前31位为数值位,第32位为符号位(0为正数,1为负数)。例如整数10的二进制形式为00000000 00000000 00000000 00001010(
或者更简洁的1010)
。
负数采用二进制补码表示。二进制补码等于数值绝对值的反码加1(计算一个数值的补码细分为三步:其一求目标值绝对值的二进制码,其二求二进制反码(将1替换为0,将0替换为1),其三将得到的二进制反码加1)。如下求-4的二进制码:
//第一步:求绝对值的二进制码
00000000 00000000 00000000 00000100//第二步:求二进制码反码
11111111 11111111 11111111 11111011//第三步:二进制反码加1
11111111 11111111 11111111 11111100
按位与
以特定规则组合操作数并返回一个新值(比较操作数二进制形式对应比特位上的二进制数,都为1结果为1,否则为0)。
> 3 & 1
> 00000000 00000000 00000000 00000011 // 3的二进制表示
> 00000000 00000000 00000000 00000001 // 1的二进制表示
> 00000000 00000000 00000000 00000001 // 两数按位与的返回值, 3 & 1 = 1
按位或
对应比特位上任意一个数为1时结果为1。
> 3 | 1
> 00000000 00000000 00000000 00000011 // 3的二进制表示
> 00000000 00000000 00000000 00000001 // 1的二进制表示
> 00000000 00000000 00000000 00000011 // 两数按位或的返回值, 3 & 1 = 3
按位异或
比较对应比特位上的数,相同为0不同为1。异或具有可逆性,即a^b=c,则有b^c=a(1 ^ 0 = 1 => 1 ^ 0 = 1) 。
> 3 ^ 1
> 00000000 00000000 00000000 00000011 // 3的二进制表示
> 00000000 00000000 00000000 00000001 // 1的二进制表示
> 00000000 00000000 00000000 00000010 // 两数按位异或的返回值, 3 & 1 = 2//二进制比特位上
> 1 ^ 0 = 1
> 0 ^ 1 = 1
> 1 ^ 1 = 0
> 0 ^ 0 = 0> a ^ b ^ b = a
> a ^ b ^ a = b
按位非
求二进制数的反码(1变0,0变1)。其本质是操作数的负值减1。
> ~3
> 00000000 00000000 00000000 00000011 // 3的二进制表示
> 11111111 11111111 11111111 11111100 // 两数按位非的返回值, ~3 = -4
> ~3 = -4 //按位非的本质是操作数的负值减1
> ~~3 = 3 //对一个整数两次按位非,可以得到它本身
> ~~3.1 = 3 //对一个小数两次按位非,可以得到取整效果
左移
左移将所有二进制比特位向左移动指定位数,原值右侧空出的位自动补0。左移不会影响操作数的符号位。左移一位相当于将原数乘以2,依次类推,左移n位相当于将原数乘以2的n次方倍。
> 3 << 1 // 3 * 2 = 6
> 3 << 2 // 3 * 2 * 2 = 12
> 3 << 3 // 3 * 2 * 2 * 2 = 24
有符号右移
右移将除符号位外其余二进制比特位向右移动指定位数。空缺位出现在数值位左侧,符号位右侧,用符号位的值来填充空位。右移不会影响操作数的符号位。右移一位相当于原数除2后向下取整,依次类推,右移n位相当于原数除2的n次方倍后向下取整。
> 9 >> 1 // 9 / 2 = 4.5 --> 取整 --> 4
> 9 >> 2 // 9 / (2 * 2) = 2.25 --> 取整 --> 2
> 9 >> 3 // 9 / (2 * 2 * 2) = 1.125 --> 取整 --> 1
> 9 >> 4 // 9 / (2 * 2 * 2 * 2) = 0.5625 --> 取整 --> 0
无符号右移
无符号右移将所有二进制比特位向右移动指定位数,原值左侧空出的位自动补0。正数无符号右移的结果和有符号右移相同。
> -4 >>> 2
> 00000000 00000000 00000000 00000100 //-4绝对值的二级制形式
> 11111111 11111111 11111111 11111011 //反码
> 11111111 11111111 11111111 11111100 //补码
> 00111111 11111111 11111111 11111111 //右移两位,即十进制的1073741823
位运算符的实际应用
使用按位非~判断字符串中是否含有指定子串或数组中是否含有指定元素(原理:~-1 === 0)。
//判断字符串中是否含有指定子串
> url += ~url.indexOf('?') ? '&' : '?'; //url含有?号,则后面拼上&符号,否则加上?号
//数组中是否含有指定元素
> var arr = [1,2,3,4];
> if(~arr.indexOf(1)){ //arr.indexOf(1) = 0 --> ~arr.indexOf(1) = -1 --> true }
使用异或操作交换两个数的值。
> var a = 3,b = 2;
> a = a ^ bb = a ^ b // b = 3a = a ^ b // a = 2
使用按位与进行标志位判断。如某后台管理系统使用位操作管理权限(操作权限分为一、二、三级,一级用第三位表示即0b100 = 4,二级用第二位即0b010 = 2,三级用第一位即0b001 = 1)。有些功能只允许一、二级权限操作,有些只允许一、三级权限操作。如功能A只允许一二级权限操作,这个权限值可以表示为0b100 + 0b010 = 0b110 = 6。将权限值与各级权限按位与得到的结果不为0则判定为有权限,结果为0则判定为无权限。
var FLAG_1 = 4; // 0b100
var FLAG_2 = 2; // 0b010
var FLAG_3 = 1; // 0b001
// 只允许一级、二级操作:4 ^ 2 = 6(0b110)
// 原理:
> 4 ^ 2 = 6 --> 6 & 4 = 4 //有权限6 & 2 = 2 //有权限6 & 1 = 0 //无权限
异或加密是一种很简单的加密算法,在做一些简单加密时被广泛使用。利用异或的可逆性原理,若a为要加密的信息,则有一密钥b,对a和b做异或得到的结果c就是加密后的信息(只要将c与b做异或,即可得原信息a)。
var a = ['12', '22'];
var b = ['12', '12']; //密钥
var c = []; //密文
for(var i = 0; i < a.length; i++){c.push(a[i] ^ b[i]);
}
使用按位与判断一个数的奇偶。
> 3 & 1 // 1 --> 奇数 & 1 = 1
> 2 & 1 // 0 --> 偶数 & 1 = 0
使用左移实现乘法运算。使用有符号右移实现除法运算。
console.log(2 << 1); // 4 --> 2 * 2
console.log(2 << 2); // 8 --> 2 * 2 * 2
console.log(2 << 3); // 16 --> 2 * 2 * 2 * 2
console.log(2 << 4); // 32 --> 2 * 2 * 2 * 2 * 2console.log(2 >> 1); // 2 / 2 * 1 --> 1
console.log(5 >> 1); // 5 / 2 * 1 --> 2
console.log(8 >> 1); // 8 / 2 * 1 --> 4
console.log(9 >> 1); // 9 / 2 * 1 --> 4console.log(2 >> 2); // 2 / 2 * 2 --> 0
console.log(5 >> 2); // 5 / 2 * 2 --> 1
console.log(8 >> 2); // 8 / 2 * 2 --> 2
console.log(9 >> 2); // 9 / 2 * 2 --> 2
使用位运算符进行小数取整。
//利用取两次按位非、与0按位或、与0按位异或、左移0位、右移0位都可以实现小数取整效果
console.log(~~3.1); //3
console.log(3.1|0); //3
console.log(3.1^0); //3
console.log(3.1<<0); //3
console.log(3.1>>0); //3
typeof操作符
js中有六种数据类型,分别是number、string、boolean、undefined、object、function。js是一门弱语言,声明变量时无需确定变量类型,js会在运行时自动判断。typeof运算符可以用来判断对象的类型,返回的是六种数据类型的字符串形式。typeof有两种形式,其一带括号形式如typeof(123),其二不带括号形式如typeof 123。
> typeof("123") ---> "string"
> typeof({}) ---> "object"
> typeof([]) ---> "object"
> typeof(null) ---> "object"
> typeof(undefined) ---> "undefined"
> typeof(function(){}) ---> "function"
null虽是原始值,但用typeof检测的结果是object类型,这是浏览器的一个历史遗留问题。最早null是以一种代替空对象的形式出现的,用来给对象占位。所以浏览器认为null是一个对象。
typeof是唯一一个使用未定义变量不报错的,打印结果为“undefined”。
typeof(a) ---> "undefined" //a没有声明,不会报错
console.log(typeof(typeof(a))) ---> "string "
var x = 1;
if(function f() {}){ //函数变成表达式后引用会被忽略(函数名被放弃) f ---> undefinedx += typeof f; //f 未定义 typeof f ---> "undefined"
}
console.log(x);
< 1undefined
判断数据类型
function type(target){var ret = typeof(target);var template = {"[object Array]": "array","[object Object]": "object","[object Number]": "number-object", //数值类型的包装类"[object Boolean]": "boolean-object", //布尔类型的包装类"[object String]": "string-object" //字符串类型的包装类}if(target === null){return "null";}else if(ret == "object"){var str = Object.prototype.toString.call(target);return template[str];}else{return ret;}
}
void操作符
void是一元操作符,位于表达式左边,表达式可以是任意类型。void有两种形式,其一带括号形式如void(0),其二不带括号形式如void 0。void后面的表达式无论是什么都会正常执行,void会忽略表达式的返回值并始终返回undefined。
> console.log(void 0); ---> undefined
> console.log(void(0)); ---> undefined
作用一:返回undefined
undefined并不是Javascript的保留字,在个别环境中可被修改(如IE8-浏览器中可以被重写,函数作用域中也可以被重写)。使用void方式获取undefined更加安全可靠(除了采用void获取undefined值,还可以通过函数调用的方式)。
var undefined = 10; //低版本浏览器中undefined可以被重写
console.log(undefined); //IE8-浏览器下为10,高版本浏览器下为undefined
function t(){var undefined = 10; //函数作用域中,undefined可以被重写console.log(undefined); //所有浏览器下都打印10
}
> (function(){}()); //不写返回值,函数隐式返回undefined
< undefined
作用二:阻止默认事件(如填充<a>的href
确保点击时不会发生页面跳转或刷新)
超链接有时并不需要跳转或刷新页面(默认事件),仅用来触发一些交互操作。有两种方式可以阻止超链接的默认事件,其一利用void操作符,其二点击事件返回false。
<--方法一:javascript是协议限定符-->
<a href="javascript:void(0)" onclick="f()">超链接</a>
<--方法二:-->
<a href="#" onclick="f();return false;">超链接</a>
<--#包含一个位置信息,默认返回网页顶部。为避免跳转页面,需要onclick点击事件返回false-->
<--只有onclick事件返回false才能阻止默认事件,函数返回false不管用-->
<--1、可以阻止默认事件-->
<a href="#" onclick="f();return false;">超链接</a> <--2、不能阻止默认事件-->
<a href="#" onclick="f()">超链接</a>
<script>function f(){ return false; }
</script><--3、可以阻止默认事件-->
<a href="#" onclick="return f()">超链接</a>
<script>function f(){ return false; }
</script>
delete操作符
delete是一元操作符,可以用来删除对象属性或变量,删除成功返回true,失败返回false(如果delete后面的操作数是一个不存在的属性或变量返回true)。并非所有的属性和变量都能被删除,某些内部的核心属性和客户端属性不能被删除(通过var声明的变量和function声明的函数不能被删除,未经var声明的全局变量可以被删除)。
a = 123; //没有用var声明的普通变量可以被删除
delete a; //true, a被删除,访问a报错var b = 123;
delete b; //false, 用var声明的变量不能被删除delete c; //true, c没有被声明过,返回true
delete只能删除对象本身属性,不能删除原型上的属性。对象属性如果是引用值,delete仅删除对象属性本身,不会删除属性指向的对象。
var a = { name: 'lilei' };
var obj2 = {item: a //a为引用值
}
delete obj2.item; //true, obj2.item = undefined, a = { name: 'lilei' }
(function(x){delete x;return x;
}(1))
//1, 因为形参相当于用var声明的变量
instanceof操作符
用法:A instanceof B
官方解释:用于判断A对象是不是B构造函数构造出来的。
本质:判断A对象的原型链上是否有B构造函数的原型
function Person () { }
var person = new Person();
> person instanceof Person
< true
> person instanceof Object
< true> [] instanceof Array
< true
> [] instanceof Object
< true
> {} instanceof Array
< false
in操作符
二元操作符。左侧操作数必须是字符串类型,或可转换为字符串类型的其他类型。右侧操作数必须是数组或对象。若左侧操作数是右侧操作数或其原型的一个属性名,则返回结果为true,否则返回false。
var obj = { name: 'jpf' };
console.log('name' in obj); // true
var arr = ['name', 'age'];
console.log(0 in arr); // true, 相当于判断arr[0]是否存在
二、条件语句
if语句
基于不同条件执行不同动作。
if(true){}
if(false){}else if(false){}else{}
switch语句
基于不同条件执行不同动作。首先设置表达式n,随后表达式的值会与结构中每个case值做比较(case里面可以放任何类型的值),如果值匹配,则与该case关联的代码块将被执行。case语句执行完后会默认继续执行下一个case关联的代码块,为阻止下漏需使用break跳出switch。使用default关键词规定匹配不存在时做的事情。
//标准形式
switch(n){case 1://...break;case 2://... break;default://...break;
}
switch(n){case 1:case 2://... break;default://... break;
}
//case1和case2都会执行表达式2,这种方式也是可行的,用来避免重复代码
三、循环语句
for循环
for循环共三个参数,第一个和第三个参数可以不放在for后面的括号中。第二个参数是一个表达式,只要对应的布尔值为true就可以执行循环体内的语句。for循环的执行体可以省略,后面直接加分号就行。
for(var i = 0; i < 10; i++){}
//<=>
var i = 0;
for(; i < 10;){ //此时的for循环就相当于while循环i++;
}
//要求打印出0-100?
var i = 101;
for(;i--;){ console.log(i);
}
//101对应的布尔值为true,判断完毕后执行--操作,之后才会执行循环体内的语句,所以以101起始
//i等于0时,for循环停止
//for循环的执行体可以省略,后面直接加分号就可以
for(var i = 0; i < 10; i++);
console.log(i); // 10
while循环
while循环的底层机制就是for循环,while循环是for循环的简化版。
while(){ } <=> for(; true; ){ } //while循环是for循环的简化版
> var n = 1;
> while( n-- ){console.log(n);}
< 0
//1对应的布尔值为true,判断完毕后执行--操作,之后才会执行循环体内的语句,所以打印0
do/while循环
do/while循环和while循环是一个机制。while循环满足条件时执行,do/while循环不管是否满足条件,先执行一次,判断成立后再执行第二次。不推荐使用。
break和continue
break终止循环语句并跳出整个循环。continue终止本次循环并进入下次循环。break和continue必须放在循环里,否则报错。
四、with语句
with语句可以将一个对象放在指定代码块作用域链的最顶端。with语句虽然可以改变作用域链,但效率很低,在开发中基本不会使用。ES5.0严格模式禁用with语句。with语句是一种重复引用同一对象的多个属性的快捷方式,不需要重复引用对象本身。
var obj = {a: 1,b: 2
}
with(obj){ //obj在with代码块作用域链的最顶端,obj就相当于一个AO, with代码块优先访问obj里面的内容console.log(a); //1, 实际访问的是obj.aconsole.log(b); //2a++; //直接修改obj.a的属性值
}
var obj = {a: 1,b: 2
}
with(obj){ var a = 12; //a指的obj.a, var没有发挥声明新变量的作用
}
obj.a; //12
//with括号中必须存在一个对象
with(true){ } //存在包装类,不报错
with(1234){ } //存在包装类,不报错
with("12"){ } //存在包装类,不报错with(null){ } //报错, Uncaught TypeError: Cannot convert undefined or null to object
with(){ } //报错, Uncaught SyntaxError: Unexpected token )