js是一种轻量级的脚本语言,它可以部署在多种环境,最常见的部署环境就是浏览器。
所谓的脚本语言,指的是它不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序的操作方法
一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:
- 核心(ECMAScript)
- 文档对象模型(DOM) Document object model (整合js,css,html)
- 浏览器对象模型(BOM) Broswer object model(整合js和浏览器)
JavaScript 引入的两种方式:
1.直接在style 中 的script 标签中写
<script> // 在这里写你的JS代码 </script>
2.导入外部JavaScript的文件
<script src="myscript.js"></script>
JavaScript的语言规范:
1.注释:
/ 这是单行注释 /* 这是 多行注释 */
2.变量声明: 在Javascrip中使用新变量前要进行声明.
- JavaScript的变量名可以使用_,数字,字母,$组成,不能以数字开头。
- 声明变量使用 var 变量名; 的格式来进行声明
var name = "Alex"; var age = 18;
还可以这么写:
<script> console.log('你好'); var name; name='xiaohong'; console.log(name) </script>
变量规则:必须遵守
1.一个变量名字可以由数字、字母、下划线、美元、符号、$、组成
2.严格区分大小写
3. 不能由数字开头
4.不能是关键字
规范:建议遵守
- 变量名有意义
- 遵循驼峰命名规则,由多个单词组成时,从第二个单词开始首字母大写 passWord
JavaScript 中的数据类型
查看类型的方法为typeof
var name; name='xiaohong'; console.log(typeof name)
JavaScript拥有动态类型
1.数字类型number
JavaScript不区分整型和浮点型,就只有一种数字类型number, NAN也是一种number类型
常用方法:
Number 将字符串转换成数字,这个字符串必须全部是数字,不能由字母
var name
name='222.123'
console.log(Number(name))
//结果为
222.123
parseInt将字符串中的数字部分转换为整数,如果字符串不是以数字开头的,将返回NAN(not a number),注意将小数部分取整。字符串可以含有别的字符
var a1 = parseInt('123er56'); console.log(a1) //结果为 123
parseInt("123") // 返回123 把字符串的数字转换为数字
parseInt("ABC") // 返回NaN,NaN属性是代表非数字值的特殊值。该属性用于指示某个值不是数字。
parseFloat("123.456") // 将字符串中的数字部分转换出来,字符串可以含有别的字符返回123.456
隐式转换:就是系统默认的不需要加声明就可以自动转换
console.log(1+true); console.log(1+false); console.log(1+null); console.log(1+undefined); //结果为 2 1 1 NaN
由此说明: true等于1. false=0 null 是一个空,不能单纯作为0处理 undefined也等于NAN
2.字符串:string
注意不区分空字符,只要用引号,引起来,就是字符串
字符串拼接的方法 推荐使用'+'
obj.length 注意length后面没有括号:返回字符串的长度.
obj.trim() 移除字符串左右两边的空格,但是不能移除字符串中间的空格
obj.trimLeft() 移除字符串左边的空格
obj.trimRight() 移除字符串右边的空格
obj.charAt(index) 通过索引查找对应的元素. 不可以用负值,负值会返回空字符串
obj.concat(value, ...): 字符串的拼接,不推荐使用这个用+号
obj.indexOf(字符串中的元素, startindex: 通过元素找元素的索引,如果有多个只显示最左边的那个. 如果找不到则返回-1, indexstart 可以省略,如果省略表示从头开始查找
如果不省略则从indexstart处开始查找,但是得到的结果还是和从开头找的结果一样,如果 startindex 是负数,则 startindex 被当作零。如果它比最大的字符位置索引还大,结果为-1找不到。
obj.substring(from, to) :和python中的字符串切片一样前包后不包, 但是不能用负数来表示, to可以不写
name; "sticker, china" var name11=name.substring(2,5); undefined name11; "ick"
obj.slice(start, end): 返回一个新的字符串。包括字符串 stringObject 从 start 开始(包括 start)到 end 结束(不包括 end)为止的所有字符。可以接受负数,to可以不写.
obj.toLowerCase(): 字符串变为小写.
obj.toUpperCase():字符串变为大写.
obj.split(separator,howmany):用于把一个字符串分割成一个列表(数组)。separator 字符串或正则表达式,从separator处切开,但是不包含separator自身,howmany 用于指定你需要列表中有几个符合条件的字符,当不填时会全部显示显示.
结果:
(11) ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
范例二:
var n2=n.split('',2);
结果
["h", "e"]
其他类型转字符串
1. String(数据类型) :所有类型都可以转
2.数据类型.toSring():不支持undefined和null
3.使用加法运算
在js里面+有两个含义
字符串拼接:只要+任意一边是字符串,就会进行字符串拼接
加法运算:只有两边都是数字才会进行数字运算
3.布尔类型boolean
注意:区别于Python,true和false都是小写。
var a = true; var b = false;
注意: 返回false的情况:
- " " 即:空字符串
- 0
- -0
- undefined
- false
- null
- NaN
其他的的都返回True ,包括空数组和对象
比较运算符
比较运算符在逻辑语句中使用,以测定变量或值是否相等。
注意: '=' 是赋值
== 是等于 仅判断值是否相等,不管类型的事
===是强等于 比较值和类型是否都相等.
在JS世界中,一共有这几种情况被认定为假:fase,undefined,'',null,0与神奇的NaN。
console.log(0&&1); 左边为假,不走了,打印结果为0;
console.log(undefined&&1);左边为假,程序不走了,弹出的结果为undefined;
console.log(true&&'');左边为真,程序继续,弹出的结果为'';
console.log(NaN&&true);左边为假,程序不走了,弹出NaN;
逻辑运算符
逻辑运算符用于测定变量或值之间的逻辑。
var y=1000
console.log(y&&y.toString()) // 当y为真时,才执行toString方法
var z = ""
console.log(z|| '这个家伙很懒,什么也没有留下') // 当z为假时,才会执行后边
++递增
有两种a++ 和++a
当a++或++a,单独成行的时候,a在原来的基础上相当于加了1,
var a = 10; a++; console.log(a) //结果等于 11
a++ 先运算再加1 区别是 a++必须遇到+号才加一(单独一行不算)
++a 先加1在运算 ++a,不需要遇到+号就能加一
var a = 10; var b = 10; var result = a++ + a ; //结果等于21,思路: a++本身等于10,当它经过+后变为11,然后加上a就是21 var response = b++ + ++b; //结果等于22,思路分析,b++本身等于10经过+后,变为11,而++b不需要经过+号就能变为11
区别:
前置++ ++再前先计算再赋值
var a=10
document.log(++a);// 会返回11
document.log(a); //并且把a的值变成11
后置++ ++在后先赋值再计算
var a=10
document.log(a++);// 会返回10
document.log(a); //并且把a的值变成11
--同理
var m=10 ,res
res=m++ +--m +m-- + ++m
document.write(m);// 会返回10
document.write(res); //40
三元表达式
JavaScript 还包含了基于某些条件对变量进行赋值的条件运算符。
语法
var name=(condition)?value1:value2
当condition为true时,执行value1的结果,否则执行value2的结果。
例子:
var a = 22;
var age = a > 5 ? 'a大于5':'a小于5';
alert(age)
高阶的多个数的比较
var a = 22; var b = 12; var c = 52; var maxNum = a > b ? a > c ? a : c : b > c ? b : c; alert(maxNum) //书写顺序 //第一 a>b?a:b 先比较ab //第二 a>b?a>c?a:c :b //然后c再和a比 //第三步 a>b?a>c?a:c:b>c?b:c //然后c再和b比
//更好的理解的写法,他俩都和第三个数比
a > b ? (a > c ? a : c ): (b > c ? b : c)
4.数组
类似于Python中的列表。
obj.length 返回数组中的元素个数
obj.push(ele):数组尾部添加一个或多个元素
obj.unshift(ele):向数组的开头添加一个或更多元素,并返回新的长度。
var a=[1,2,5,6,8]; a.unshift('1'); console.log(a)
结果:
["1", 1, 2, 5, 6, 8]
obj.pop(): 删除数组的最后一个元素。
obj.shift()删除数组的第一个元素。
obj.slice()返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。
obj.reverse()反转
obj.join(seq):将数组元素连接成字符串
obj.concat(val, ...):连接数组
遍历数组中的元素:
var a=[1,2,5,6,8]; for (var i=0;i<a.length;i++){ console.log(a[i]); }
5.对象
在 JavaScript 中,对象是一组无序的相关属性和方法的集合,对象是由属性和方法组成。
有键值构成,键值之间用冒号隔开,大括号末尾要使用分号结束
相当于python中的字典
注意:
- 属性可以不加引号,但是一般都加
- 最后一个键值对后边不加逗号
// 第一种使用对象字面量创建对象 var obj = { 'name':"小明", 'age':11 } console.log(obj.name) // 第二种使用new Object创建对象 var obj2 =new Object() obj2.name="订单" console.log(obj2)
第三种使用构造函数创建对象
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
构造函数的封装格式: function 构造函数名(形参1,形参2,形参3) { this.属性名1 = 参数1; this.属性名2 = 参数2; this.属性名3 = 参数3; this.方法名 = 函数体; } 构造函数的调用格式 var obj = new 构造函数名(实参1,实参2,实参3) 以上代码中,obj即接收到构造函数创建出来的对象。
用例
function Starts(name,age,sex,sayH){ this.name=name; this.age=age; this.sex=sex; this.sayH=sayH; } var sayH=function(){ console.log("大家好") } //创建对象 var star_obj = new Starts('Tom',11,'男',sayH)
对象里边可以有方法:
var star = { name : 'pink', age : 18, sex : '男', sayHi : function(){ // 匿名函数 alert('大家好啊~'); } };
//
star.sayHi(); // 调用 sayHi 方法,注意,一定不要忘记带后面的括号
删除 使用delete关键字
var obj = { 'name':"小明", 'age':11 } // 第一种 delete obj.name //第二种 delete obj['name']
对象取属性值的方法有两种:第一种点运算符,第二种,中括号
var a = {"name": "Alex", "age": 18}; console.log(a.name); //第一种 console.log(a["age"]);//第二种
点运算符和中括号运算符的区别?
- 点运算符不可以点一个数字,[ ] 可以。
- 点运算符不可以通过字符串变量,访问一个对象的属性。
- 点运算符可以将js中的关键字,作为对象的属性名添加,而中括号不可以。
var obj = { 'hero':'钢铁侠' }; var str = 'hero'; console.log(obj.str); console.log(obj[str]) //第一个结果为undefined // 第二个结果为钢铁侠
遍历对象中的内容:
var a = {"name": "Alex", "age": 18}; for (var i in a){ console.log(i, a[i]); }
6.null和undefined
- undefined表示的是当声明的变量未初始化时,该变量的默认值是undefined。还有就是函数无明确的返回值时,返回的也是undefined。
undefined
是全局对象的一个属性。也就是说,它是全局作用域的一个变量。undefined
的最初值就是原始数据类型undefined
。一个没有被赋值的变量的类型是undefined。如果方法或者是语句中操作的变量没有被赋值,则会返回undefined,一个函数如果没有返回
值,就会返回一个undefined值。- null表示值不存在
undefined表示没有声明和赋值变量,就使用该变量。
null声明了变量并且变量值是null。相当于python中的None
var a; a = null; console.log(typeof a) //输入的结果为 object
出现underfine的情况有两种:
1、变量没赋初始值
2. 变量没有声明。
3、函数没有返回值
第一种情况: <script> var a; alert(a);//这里没有初始化值,会出现undefined </script> 第二种情况 console.log(typeof a1) //没有声明和赋值 第三种情况: <script> var a='1'; function k(){ } a=k();//这里函数没有返回值,会出现undefined </script>
类型查询
typeof "abc" // "string" typeof null // "object" typeof true // "boolean" typeof 123 // "number"
流程控制
if
注意当if后边的括号内是负性内容(表示否定的词)的时候,不可以进入分支内容负性内容包括:null,""(空的字符串), undefined,false,0,NAN
if (undefined){ console.log('nihoa') }
if-else
var a = parseInt(prompt('请输入您的年龄')); if (a > 18) { alert('你可以去网吧了') } else { alert('你不可以去网吧,赶紧回家写作业') }
if-else if-else
var a = 10; if (a > 5){ console.log("a > 5"); }else if (a < 5) { console.log("a < 5"); }else { console.log("a = 5"); }
switch
语句用于基于不同条件执行不同动作,效率比if else要高点额很多
// d是一个变量不能是语句
var x; var d = new Date().getDay(); switch (d) { case 0 : x = '今天休息'; break; case 1 : x = '今天休息'; break; if (d > 1) { x = '今天要上班'; break; } } alert(x)
var code = Number(prompt('请输入订单状态')) switch (code) { case 1: document.write("未付款") break; case 2: document.write("已付款") break; case 3: document.write("已發貨") break; case 4: document.write("已完成") break; default : //不符合要求时走这里 document.write("出错了") }
循环
任何循环语句:都有4个条件
- 初始化变量。例如 var i =0
- 循环条件,例如i<10
- 循环体,例如console.log(i)
- 迭代条件。i++
for
for (var i=0;i<10;i++) {
console.log(i);
}
for in
var person = [1, 3, 4, 5, 6]; for (var k in person) { console.log(k) }
while
var i = 0; while (i < 10) { console.log(i); i++; }
break 和 continue
它们的用法和python的一样
内置对象和方法
JavaScript中的所有事物都是对象:字符串、数字、数组、日期,等等。在JavaScript中,对象是拥有属性和方法的数据。
对象只是带有属性和方法的特殊数据类型。
创建对象:
通过 JavaScript,您能够定义并创建自己的对象。
var person=new Object(); // 创建一个person对象
person.name="Alex"; // person对象的name属性
person.age=18; // person对象的age属性
Date对象
创建Date对象
//方法1:不指定参数 var d1 = new Date(); console.log(d1.toLocaleString()); //方法2:参数为日期字符串 var d2 = new Date("2004/3/20 11:12"); console.log(d2.toLocaleString()); var d3 = new Date("04/03/20 11:12"); console.log(d3.toLocaleString()); //方法3:参数为毫秒数 var d3 = new Date(5000); console.log(d3.toLocaleString()); console.log(d3.toUTCString()); //方法4:参数为年月日小时分钟秒毫秒 var d4 = new Date(2004,2,20,11,12,0,300); console.log(d4.toLocaleString()); //毫秒并不直接显示
Date对象的方法: var d = new Date(); //getDate() 获取日 //getDay () 获取星期几 从星期天开始 //getMonth () 获取月(0-11) //getFullYear () 获取完整年份 //getYear () 获取年 //getHours () 获取小时 //getMinutes () 获取分钟 //getSeconds () 获取秒 //getMilliseconds () 获取毫秒 //getTime () 返回累计毫秒数(从1970/1/1午夜)
json对象
var str1 = '{"name": "Alex", "age": 18}'; var obj1 = {"name": "Alex", "age": 18};
// 对象转换成JSON字符串 var str = JSON.stringify(obj1); 注意Json需要大写
// JSON字符串转换成对象 var obj = JSON.parse(str1);
regexp 对象
RegExp 是正则表达式的缩写。
// 创建RegExp对象方式
var reg1 = new RegExp("pattern", [flags]);
pattern:正则表达式的文本
[flags]: 匹配模式,这个参数可选 该标志有以下值的任意组合
g :
全局匹配;找到所有匹配,而不是在第一个匹配后停止
i :
忽略大小写
m :
多行; 将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。
u: Unicode; 将模式视为Unicode序列点的序列.
y
粘性匹配; 仅匹配目标字符串中此正则表达式的lastIndex属性指示的索引(并且不尝试从任何后续的索引匹配)。
RegExp 对象的方法
RegExp 对象有 3 个方法:
test():检索字符串中的指定值。返回值是 true 或 false。
1 var part2=new RegExp('e'); 2 undefined 3 part2.test("The best things in life are free"); 4 结果true
exec() :检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null,检索字符串中指定的值。返回找到的值,并确定其位置。
var part2=new RegExp('e');
part2.exec("The best things in life are free");
结果;["e", index: 2, input: "The best things in life are free"]
RegExpObject.compile(regexp,modifier):用于在脚本执行过程中编译正则表达式,也可用于改变和重新编译正则表达式。regexp 正则表达式。modifier规定匹配的类型。"g" 用于全局匹配,"i" 用于区分大小写,"gi" 用于全局区分大小写的匹配。
String对象与正则结合的4个方法
ar s2 = "hello world"; s2.match(/o/g); // ["o", "o"] 查找字符串中 符合正则 的内容 s2.search(/h/g); // 0 查找字符串中符合正则表达式的内容位置 s2.split(/o/g); // ["hell", " w", "rld"] 按照正则表达式对字符串进行切割 s2.replace(/o/g, "s"); // "hells wsrld" 对字符串按照正则进行替换
其中
s2.match(/o/g)下边式子的缩写,这样就不用新定义的对象了
var s2="hello, world"; var n = new RegExp("o","g"); console.log(s2.match(n ));
//RegExp对象 //创建正则对象方式1 // 参数1 正则表达式 // 参数2 验证模式:g(global)和i(忽略大小写) // 用户名只能是英文字母、数字和_,并且首字母必须是英文字母。长度最短不能少于6位 最长不能超过12位。 // 创建RegExp对象方式 var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$", "g"); // 匹配响应的字符串 var s1 = "bc123"; //RegExp对象的test方法,测试一个字符串是否符合对应的正则规则,返回值是true或false。 reg1.test(s1); // true // 创建方式2 // /填写正则表达式/匹配模式 var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/g; reg2.test(s1); // true // String对象与正则结合的4个方法 var s2 = "hello world"; s2.match(/o/g); // ["o", "o"] 查找字符串中 符合正则 的内容 s2.search(/h/g); // 0 查找字符串中符合正则表达式的内容位置 s2.split(/o/g); // ["hell", " w", "rld"] 按照正则表达式对字符串进行切割 s2.replace(/o/g, "s"); // "hells wsrld" 对字符串按照正则进行替换 // 关于匹配模式:g和i的简单示例 var s1 = "name:Alex age:18"; s1.replace(/a/, "哈哈哈"); // "n哈哈哈me:Alex age:18" s1.replace(/a/g, "哈哈哈"); // "n哈哈哈me:Alex 哈哈哈ge:18" 全局匹配 s1.replace(/a/gi, "哈哈哈"); // "n哈哈哈me:哈哈哈lex 哈哈哈ge:18" 不区分大小写 RegExp对象
实例
在字符串中全局搜索 "man",并用 "person" 替换。然后通过 compile() 方法,改变正则表达式,用 "person" 替换 "man"
var str='Every man in the world! Every woman on earth!'; patt=/man/g; str2=str.replace(patt,"person"); console.log(str2);
结果:
"Every person in the world! Every woperson on earth!"
match对象
abs(x) 返回数的绝对值。 exp(x) 返回 e 的指数。 floor(x) 对数进行下舍入。 log(x) 返回数的自然对数(底为e)。 max(x,y) 返回 x 和 y 中的最高值。 min(x,y) 返回 x 和 y 中的最低值。 pow(x,y) 返回 x 的 y 次幂。 random() 返回 0 ~ 1 之间的随机数。 round(x) 把数四舍五入为最接近的整数。 sin(x) 返回数的正弦。 sqrt(x) 返回数的平方根。 tan(x) 返回角的正切。
函数
JavaScript 函数通过 function
关键词进行定义,其后是函数名和括号 ()。
函数名可包含字母、数字、下划线和美元符号(规则与变量名相同)。
圆括号可包括由逗号分隔的参数
// 声明式函数,可以先调用函数再声明函数 function f(n) {
var m=n-1 return m } f(3)//调用 // 赋值式函数 不可以先调用再赋值 var f1=function(){ }
函数没有返回值,则返回undefined
预解析
预解析就是js代码的编译和执行
js是一个解析型语言,就是在代码执行之前,先对代码进行通读和解释,然后再执行代码,也就是说我们的js代码在运行的时候会经历两个环节解释代码和执行代码
解释代码:
因为在所有代码执行之前进行解释 ,需要解释的内容有两个
- 声明式函数
- 在内存中先声明有一个变量名是函数名,并且这个名字代表的内容是一个函数
- var 关键字
- 在内存中先声明有一个变量名
js 的变量和函数提升
javaScript中的变量和函数提升是指在代码执行之前,JavaScript引擎将变量和函数的声明提升到其作用域的顶部。这意味着在变量和函数声明之前就可以访问它们。
变量和函数提升的行为主要针对使用var关键字声明的变量和使用function关键字声明的函数。
下面是一些关于变量和函数提升的重要概念:
变量声明提升:在作用域内,使用var关键字声明的变量会在代码执行之前被提升到自己的作用域顶部,但变量的赋值不会被提升。这意味着你可以在变量声明之前访问变量,但它的值会是undefined。
console.log(myVariable); // 输出:undefined var myVariable = 10;
上面的代码会在控制台输出undefined,因为变量myVariable的声明被提升,但是赋值操作在之后才执行。
函数声明提升:使用function关键字声明的函数会在代码执行之前被提升到作用域顶部。这意味着你可以在函数声明之前调用函数。
myFunction(); // 输出:Hello function myFunction() { console.log('Hello'); }
上面的代码会在调用myFunction()之前输出Hello,因为函数声明被提升到了作用域顶部。
需要注意的是,变量和函数提升是在编译阶段发生的,并不意味着实际的代码顺序被改变。代码的书写顺序仍然是保持不变的,只是在代码执行之前变量和函数的声明被提升。
对于使用let和const声明的变量,它们在声明之前是不可访问的,这种行为被称为"暂时性死区(Temporal Dead Zone,TDZ)",而不是像var一样发生变量提升。这是因为let和const具有块级作用域,并且在声明之前尝试访问变量会抛出错误。
综上所述,了解JavaScript中的变量和函数提升对于理解代码执行顺序和避免潜在的问题非常重要。建议在代码中始终在作用域的顶部声明变量和函数,以提高可读性和可维护性。
————————————————
版权声明:本文为CSDN博主「577wq」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41045651/article/details/131592909
优先级1 :函数声明优先级高于变量声明优先级
//同时声明变量a和函数a var a; function a() {} alert(typeof a); //显示的是"function",初步证明function的优先级高于var。 //先声明函数后声明变量,证明上边的例子不是function覆盖了变量 function a() {} var a; alert(typeof a); //显示的仍是"function",而不是"undefined",即function的优先级高于var。 //声明了变量的同时赋值 function a() {} var a = 1; alert(typeof a); //number,此时不是function了。 //说明:"var a=1"相当于"var a;a=1",即先声明,后赋值,"a=1"相当于把a重新赋值了,自然就是number!
优先级2 函数内部只要用var定义了和外部相同的变量,函数将不再向上找外部的变量
var value = 'hello'; function show() { alert(value); if (!value) { var value = 'function'; //正是因为这里用var定义了value,才导致第一个alert是undefined } alert(value); } show() //此处调用函数依次弹出 "undefined", "function"//上例相当于 var value = 'hello'; function show() { var value; //注意这行 alert(value); if (!value) { value = 'function'; //这行去掉var } alert(value); } show() //1.如果上列中show内部定义value未用var,则会用到外部的变量,弹出"hello", "hello"。 //2.如果函数内部未定义value,也能获取到外部的value值。
优先级3 :匿名函数不会向上提升
优先级4: 不同<script>块中的函数互不影响
<script> getName() var getName = function () { alert('closule') } <script> <script> function getName() { alert('function') } <script> //代码执行报错:TypeError: getName is not a function //因为第一个<script>块中getName()函数未定义,匿名函数又不会向上提升
作用域
1)全局变量 只有在浏览器关闭的时候才会销毁 ,比较占内存资源
(2)局部变量 在我们程序执行完毕就会销毁 ,比较节约内存资源
作用域的查找机制只能是向上查找,不能向下找
作用域链:内部函数访问外部函数的变量 采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链 就近原则
全局作用域
1. 所有未定义直接赋值的变量拥有全局作用域,如果在函数内部没有声明 直接赋值的变量也属于全局变量
function fn() { age = 19; console.log(age); } fn(); console.log(age); // 19
2.定义在最外层的变量
var str = "Hello World!"; function myFun(){ document.write(str); // 输出:Hello World! } myFun(); document.write(str); // 输出:Hello World!
3. 所有 window 对象的属性拥有全局作用域,例如 window.name、window.location、window.top 等
局域作用域
在js中只有函数才能生成一个局部作用域,别的都不行
赋值规则
- 当你想给一个变量赋值的时候,那么就先要找到这个变量,再给他复制
- 变量赋值规则为:
- 先在自己的作用域内找,有就直接赋值
- 没有就去上一级找,有就赋值
- 如果一直找到全局作用域都没有,那么就把这个变量定义为全局变量,再给他赋值
function fun(){ console.log(num); a=20; } fun(); console.log(a) // 结果为20 //全局作用域内没有这个变量,直接定义为全局变量并赋值