10.Window对象&提升
Window对象
- 在浏览器中,浏览器为我们提供了一个window对象,可以直接访问
- window对象代表的是浏览器窗口,通过该对象可以对浏览器窗口进行各种操作
- 除此之外window对象还存储JS中的内置对象和浏览器的宿主对象(浏览器所提供的对象,例如alert())
- window对象的属性可以通过window对象访问,也可以直接访问
- 函数可以认为是window对象的方法
- 向window对象中添加的属性会自动成为全局变量
function fn2(){}
console.log(fn2 == window.fn2) //true
window.c = "我是c"
console.log(c); //我是c
var用来声明变量,作用和let相同,但var不具有块作用域(但有函数作用域)
- 在全局中使用var声明变量,都会作为window对象的属性保存
- 使用let声明的变量不会存储在window对象中,而是存储在一个秘密的小地方(同为全局变量优先访问)
var a = "我是a"
let b = "我是b"
console.log(a == window.a) //true
console.log(b == window.b) //false
补充
- 使用function声明的函数,都会作为window的方法保存
- 在局部作用域中,如果没有使用var或let声明变量,则变量会自动成为window对象属性,也就是全局变量(不建议这样写)
<script>
function fn1() {
d = "我是fn1" //未声明,默认为window对象的属性,成为全局变量
}
fn1() //应为局部作用域声明的变量只有在调用的时候创建,所以要调用fn1,此时d变量创建成功
console.log(d);
console.log(fn1 == window.fn1) //true,fn1函数为window对象的方法
</script>
提升(一点用没有)
但面试就喜欢问一些没用的东西,没有的你都知道那有用的你肯定也会。
- 什么是提升?
就是在其他代码执行前先被拿出来执行
- 为什么要提升呢?
主要是解决空间分配的问题,提前把变量函数拿出来根据他们的大小预留足够的空间,提高代码的质量。不只是JS其他语言也都有“提升”
1. 变量的提升
- 使用var声明变量,它会在所有代码执行前被声明
- 所以我们可以在变量声明前就访问变量(此时变量存在但未赋值是undefined)
<script>
console.log(a);
//a = 10 //window.a = 10 //a is not defined
var a = 10 //undefined
</script>
2. 函数的提升
- 使用
函数声明创建的函数
,会在其他代码执行前被创建 - 所以我们可以在函数声明前调用函数
fn() //我是fn函数
function fn() {
console.log("我是fn函数")
}
fn1() //fn1 is not a function,这里只是变量fn1被提升,fn1并未赋值
var fn1 = function () {
console.log("我是fn1函数");
}
//注意:必须是function开头的函数才能提前调用
3. let声明的变量实际也会提升,但是在赋值之前解释器禁止对该变量访问
练习1
<script>
var a = 1
function fn() {
a = 2 //给a赋值,先找到a,由于这里并没有对a声明,所以向上一层找。找到var a = 1,对a重新赋值为2
console.log(a); //2
}
fn()
console.log(a); //2
</script>
练习2
<script>
//变量和函数的提升同样适用于函数作用域
var a = 1
function fn() {
console.log(a); //undefined
//这里a为局部变量,受函数体限制不能被外界访问,和外界互不干涉
var a = 2
console.log(a); //2
}
fn()
console.log(a); //1
</script>
练习3
<script>
//定义形参就相当于在函数中声明了对应的变量,但没有赋值
var a = 1
function fn(a) {
console.log(a); //undefined
//给形参赋值
a = 2
console.log(a); //2
}
fn()
console.log(a); //1
</script>
练习4
<script>
//定义形参就相当于在函数中声明了对应的变量,但没有赋值
var a = 1
function fn(a) {
console.log(a); //1
//给形参赋值,形参是局部变量,并不会影响外部的全局变量a
a = 2
console.log(a); //2
}
fn(a)//将全局变量a的值传给fn的形参a
console.log(a); //1
</script>
练习5
<script>
console.log(a); //ƒ a() {alert(2)}
var a = 1 //执行
console.log(a); //1
function a() { //不执行,被提前执行过了
alert(2)
}
console.log(a); //1
var a = 3 //执行
console.log(a); //3
var a = function () { //执行,只有function a() {}形式函数会被提前
alert(4)
}
console.log(a); //ƒ a() {alert(4)}
var a //不执行,被提前执行过了
console.log(a); //ƒ a() {alert(4)}
</script>