建议使用letconst代替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()


报错消失.


全局污染

  • 这是一个非常坏的习惯,一定要先letconst,再使用!
// 全局污染:这是一个非常坏的习惯,比熬夜还坏!
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


严格模式会管它出现以下的代码,而不会管它以上的代码.