建议使用
let
和const
代替var
体验typeof
var a = 'dust'
console.log(typeof a)
var b = 99
console.log(typeof b)
var c = []
console.log(typeof c)
var d = {
hello: 1 }
console.log(typeof d)
console.log(typeof d.hello)
// e没有定义,直接输出它的类型,会是什么呢?
console.log(typeof e)
运行结果:
e没有定义,但是typeof e
输出了undefined,这就是JS的特性:变量提升
但是如果执行如下语句
console.log(e)
则会报错.
作用域问题
建议
let a = 'hello,outside'
function fun() {
let a = 'hello,inside'
console.log(a)
}
fun()
console.log('after:', a)
运行结果:
这个就不多说了,看懂就好.
let a = 'hello,outside'
console.log('before:', a)
function fun() {
a = 'hello,inside'
console.log(a)
}
fun()
console.log('after:', a)
暂时性死区
function run(a = b, b = 3) {
}
run()
反过来:
function run(a = 3, b = a) {
console.log('success!')
}
run()
报错消失.
全局污染
- 这是一个非常坏的习惯,一定要先
let
或const
,再使用!
// 全局污染:这是一个非常坏的习惯,比熬夜还坏!
function fun() {
a = 'dust'
console.log('inside:', a)
}
fun()
// 你已经污染到了函数外!
console.log('你已经污染到了函数外! outside:', a)
var a = 'outside'
console.log('outside:', a)
块作用域
- 明白为什么要用let,不用var
var i = 99
for (var i = 0; i < 3; i++) {
console.log('i =', i)
}
console.log('outside i =', i)
//这好吗?这不好!
let j = 99
for (let j = 0; j < 3; j++) {
console.log('j =', j)
}
console.log('outside j =', j)
- var不具有块作用域,也是一种污染,这样很不好.
- let具有块作用域,看运行结果,就很美好.
.bind(window)()的使用
- 立即执行函数,也是有块作用域的,不会污染到其它代码
test5.js
(function () {
var $ = (window.$ = {
})
$.web = 'dust'
var url = 'dust,hello'
$.getUrl = function () {
return url
}
}.bind(window)())
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="./test5.js"></script>
</head>
<body>
<script> console.log('in text.html:', $.getUrl()) </script>
</body>
</html>
输出:
用花括号配合let使用:优化代码
{
let $ = (window.$ = {
})
$.web = 'dust'
let url = 'dust.com'
let site = 'DUST'
$.getUrl = function () {
return url
}
}
运行结果
const的使用
以下代码会发生什么?
const a = 'dust1'
const a = 'dust2'
会报错
const
不允许修改吗?
const a = 'dust1'
function fun() {
const a = 'dust2'
console.log(a)
}
fun()
没有报错
Window全局对象污染
- 获取屏幕左侧距离
console.log(window.screenLeft)
拖动一下,刷新,值会变
如果执行以下代码呢?
var screenLeft = 99
console.log(window.screenLeft)
不会再随着拖动而改变
但是如果使用let
,世界就不一样了(let
真美妙啊!)
let screenLeft = 99
console.log(window.screenLeft)
console.log(screenLeft)
重复声明
使用var进行重复声明的时候不会报错,但这并不是什么好事!
var a = 1
//然后我写了很多代码,忘记了自己曾经声明过a
var a = 2
console.log('var重复使用不报错(但是这并不好!)')
输出
那如果用let呢
let a = 1
let a = 2
console.log('let声明')
报错了,但这是好事
所以,用let代替var吧!
Object.freeze冻结变量
const HOST = {
url: 'www.baidu.com',
port: 8080,
}
Object.freeze(HOST)
HOST.port = 80
console.log(HOST)
在freeze后,不能再对其进行修改
传值和传地址
let a = 1
let b = a
console.log(a, b)
b = 3
console.log(a, b)
let e = {
name: 'dust' }
let f = e
console.log(e, f)
f.name = 'Miss.Corleone'
console.log(e, f)
- 对于类型为number的a和b而言,是传值,使用的不同的地址
- 而对于Object类型的e和f而言,是传址,两个变量使用的相同的地址(这是一个大坑!)
undefined
-
就和我没有对象这件事一样,都是undefined
-
这段代码我没法跟你解释,老师说"交了一个女朋友,再交第二个,总得适应一下,不能拿对第一个女朋友一样的态度对第二个女朋友."
-
但我一个都没有,所以理解不了
-
看代码吧
function show(name) {
console.log(name)
}
console.log(show())
输出
- 原来两个女朋友都是undefined吗,告辞
- (所以大家不要处对象?)
严格模式
- 好的代码习惯需要养成
- 但是路上总有一些"马路杀手"会闯红灯.闯红灯一定会出事吗?还不一定.但是闯红灯是不好的,所以需要交规
- 严格模式就相当于这个交规
- 严格模式可以帮我们遵守更多的规则
'use strict'
function fun() {
a = 10
}
console.log(a)
'use strict'
let private = 10
注意,此时private
被保留,所以不能当做变量
严格模式的作用域
let public = 10
console.log(public)
function fun() {
'use strict'
a = 10
}
console.log(a)
let private = 10
严格模式会管它出现以下的代码,而不会管它以上的代码.