1、简单程序流程
<script> say(content); function say(something) { console.log(something); } var content = '你好'; </script>
//页面加载时声明前置,content先被声明,然后执行say();此时content并未被赋值,所以结果为default。
2、js作用域
<script> function demo() { if(true) { var i = 200; } console.log(i); //js没有块级作用域,js只以函数划分作用域. } demo(); </script>
①Js没有块级作用域 ②Js只通过函数划分作用域
对于这个程序,只有一个作用域讲就是demo函数,所以console.log可以调用i的值。
3、隐式声明
<script> function say() { var x = 200; function inner() { y = 100; //隐式声明的变量会自动提升为全局变量,所以在声明变量的过程中一定要注意,不要声明隐式变量 console.log(x); } inner(); console.log(y); } say(); console.log(y); </script>执行y=100这行代码时,程序会从内向外去搜索y这个变量,最后没有找到,就会在window对象下创建这个变量,所以可以被全局调用,为全局变量。
4、同名变量
<script> function say() { var str1 = 'hello'; function inner() { var str1 = 'world'; console.log(str1); //同名变量,在不同作用域,是两个不同的变量. } inner(); console.log(str1); } say(); </script> <script> function say() { var str1 = 'hello'; var str1 = 'world'; //同名变量,在同一作用域,下面的会覆盖上面的 console.log(str1); } say(); </script>一开始将console.log(str1)放在了say();下面,导致不能打印,错误在于函数外部不能访问函数内部。
5、函数中声明的变量在整个函数中都有定义
<script> function demo() { var x = 12; function inner() { x = 200; } inner(); console.log(x); } demo(); console.log(x); </script> <script> function demo() { console.log(x); //函数中声明的变量在整个函数中都有定义。声明前置. var x = 200; console.log(x); } demo(); </script>①一开始认为第一个打印应该为12,错,因为里面那个函数将x重新赋值为200,再执行的打印操作。②第一个打印开始的时候只是声明已经执行,还没有赋值,所以是default。
6、基本数据类型(布尔,string,number,null,default)和引用数据类型object
<script> var str = 2; var str2 = str; //基本数据类型的赋值,其实就是复制了一份值 str = 200; console.log(str2); </script> <script> var people = { name: '张三', age: 20 }; var people2 = people; // people = { //这个people原来的引用被切断,开辟了一个新的内存空间.赋了新的地址. // name: '周勇', // age: 25 // }; people.name = '李四'; //引用数据类型的赋值,本质上是赋的地址. people.age = 25; console.log(people2.name); console.log(people2.age); </script>①var str2 = str这行代码与var str2 = 2代码等价,所以只为赋值。②people.name这个格式的写法才指向之前people的地址,即赋给people2的地址,而//里的写法为开辟一个新的地址,这个地址并没有赋给people2。
区分引用数据类型和基本数据类型是看声明的时候有没有{ }.