1-4
约 10362 字大约 35 分钟
2025-01-20
1,基础知识
1-1 基础知识
// 1,标识符命名规则:第一个字母必须是字母,下划线或一个美元符号。不能数字开头,通常不用汉字;
// 2,空格忽略,所以可以在代码中随意使用空格和换行;
// 3,注释 // 单行注释; /* 注释内容 */ 多行注释;
// 4,直接量(literal) 12 1.2 “hello wold” true 等等;(一般赋给变量或者用在表达式里面);
// 5,严格模式 顶部添加 “use strict”;
// 6,语句以一个分号结束,如果省略分号,则由解析器确定语句结尾;
1-2 变量
function show(){
var msg="aini";
}
show();
console.log(msg)
// 函数内用 var 定义的变量是局部变量,只能在函数内使用;
function show(){
msg="aini";
}
show();
console.log(msg)
// 不用 var,而直接赋值就是全局变量,可以在函数外边使用;
注:虽然省略了 var 可以定义全局变量,但不推荐使用这种做法,因为正在局部作用域中的全局变量很难维护。
1-3 数据类型
// 1,js 不区分浮点数和整数;
// 2,除了十进制,整数还可以用八进制和十六进制来表示;16 进制前面加 0x;8 进制前面必须有 0(或者 0o);计算或输出的时候会换算成 10 进制输出;(严格模式下 8进制无效,ES6 页不能使用的)
// 3,极大数或极小数可以用科学计数法 e 如 3e+10=3^10/3e-10=3^(-10) 加号可省略;默认情况下,会将那些小数点后面带有 6 个零以上的浮点数转换为以 e 表示的数值;
console.log(0.1 + 0.2); 不等于 0.3,而是等于 0.30000000000000004; // 所以浮点数加减不准确;
4,数据范围,由于内存限制,ESmascrip 并不能保存任意的数值;其能够表示的最小值保存在 Number.MIN_Value 中,在绝大多数浏览器中,这个值是5e-324;表示最大值保存在 Number.MAX_Value 中,值为1.7976931348623157e+308
console.log(Number.MAX_VALUE); 1.7976931348623157e+308
console.log(Number.MIN_VALUE); 5e-324
console.log(Number.MAX_SAFE_INTEGER); 9007199254740991 // 安全整数值;
console.log(Number.MIN_SAFE_INTEGER); -9007199254740991
5,想确定一个数是不是有穷的,可以使用 isFinite()函数,这个函数会判断参数是否位于最小值与最大值之间;
var a=10; // 返回为 TRUE
console.log(isFinite(a));
6,访问 Number.POSITIVE_INFINITY 和 Number_NEGATIVE_INFINITY 也可以得到正负infinity 值;既这两个属性中分别保存着 infinity 和-infinity;
console.log(Number.POSITIVE_INFINITY); infinity
console.log(Number.NEGATIVE_INFINITY); -infinity
7,NaN 非数值(not a number)用于返回一个本来要返回数值却未返回数值的情况;
注:除以 0 的结果是 infinite,不是 NaN; NaN 与任何值不相等,包括其本身;任何涉及 NaN 的计算都会返回 NaN;
console.log(3/"a"); NaN
console.log(NaN==NaN); flase
8,isNaN()函数 接受一个参数;判断这个参数可以是任何类型,其判断改参数是否“不是数值”,这个函数首先尝试把这个参数转换成数值;某些不是数值的值会直接转换成数值,比如字符串“10”,或者 Boolean,而任何不能被转换为数值的值都会导致这个函数返回 TRUE;
console.log(isNaN("number")); // 是非数字 所以 TRUE
console.log(isNaN(10)); // 是数字 所以 false
console.log(isNaN("10")); // 能转换成数字 所以 false
console.log(isNaN(NaN)); // 不是数字 所以 true
console.log(isNaN(false));// 能转换成数字 所以 false
9,string 类型 一般使用单引号 如 userName=’aini’; 空格也是字符串;
10,转义字符 \n 换行 \t 制表符 \b 退格 \r 回车 \f 进纸 \ 斜杠 \’ 单引号 \” 双引号 \nn 以 16 进制代码表示的一个字符 \unnnn 以 16 进制代码 nnnn 表示的一个 Unicode;
var src = "zero\nnetwork " // 输出到页面时,不会换行;因为 HTML 代码换行时页面中不
document.write(src);// 换行,只是多了空格;
// 书写字符串直接量可以拆分多行,每行必须加上反斜杠\结束;
11,布尔类型
var a = 10, b = 15;
console.log(a == b);
if(a == b){
console.log("相等");
}else{
console.log("不相等");
}
12,Undefined 未定义的:此类型只有一个值,既特殊的 undefined;在使用 var 声明变量,但未对其初始化;
13,Null :此类型也只有一个值,既特殊的 null 值(空值);从逻辑上看。Null 值表示一个空对象指针,而这也正是使用 typeof 操作检测 null 时会返回 object 的原因;
var car = null;
console.log(car); // null
console.log(typeof car); // object
// 注:实际上,undefined 值是派生自 null 值得,因此 ECMA-262 规定对他们相等性测试要返回 TRUE;如
console.log(null == undefined); // TRUE
1-4 复杂数据类型
1,也称为复杂的数据类型;就是一组数据和功能的集合;
var person = {};
person.name="aini";
person.age=18;
person.say = function(){
console.log("my name is aini");
console.log(person); // {name: 'aini', age: 18, say: ƒ}
2,常见的引用数据类型;
var arr = [1, 3, 4, 5];
console.log(arr); // (4) [1, 3, 4, 5]
function show(){};
console.log(show); // ƒ show(){}
var date = new Date();// Mon Sep 12 2022 14:04:42 GMT+0800 (中国标准时间)
console.log(date);
3,Object 对象
1,Object 对象时多有对象的基础,因此多有对象都具有这些基本的属性和方法;
2,toSrting(): 返回对象的字符串表示; valueOf():返回对象的字符串,数值或布尔值表示,通常与 toString()返回值相同;
var o = new Object();
var arr = new Array(1,2,3,4);
var fun = new Function("a","b");
console.log(o); // {}
console.log(arr); // (4) [1, 2, 3, 4]
console.log(fun); // ƒ anonymous(a) {b}
console.log(o.toString()); // [object Object]
console.log(arr.toString()); // 1,2,3,4
console.log(fun.toString()); // function anonymous(a) {b}
console.log(o.valueOf()); // {}
console.log(arr.valueOf()); // (4) [1, 2, 3, 4]
console.log(fun.valueOf());// ƒ anonymous(a) {b}
通常这两个方法是可以改写的,如:
var o = new Object();
o.valueOf = function(){
return "this is a object";
}
o.toString = function(){
return "this is my name";
}
console.log(o.valueOf()); // this is a object
console.log(o.toString());// this is my name
4,可变类型和不可变类型;
1,原始值是不可变类型,引用数据(复杂数据)类型属于可变类型;
var arr = [1,2];
var arr1 = arr;
arr1.push(3);
console.log(arr);
// Arr 和 arr1 指向同一个堆,所以改变一个的值,另一个也随之改变;
var arr = [1,2];
var arr1 = arr;
arr1 = [1,2,3] // (重新创建了 arr1,并覆盖了之前的数据)
console.log(arr);// [1,2]
1-5 数据类型转换
1,因为数据之间是同类型的运算,如果是不同类型的运算,需要将其转换为同一类型后再进行运算;
2,类型分两类:强制类型转换,自动类型转换;
3,自动类型转换:根据运算的语义环境,会自动进行类型转换;
var a = "2",b = "1";
console.log(a-b); // 1;
b = true;
console.log(a-b); // 1;
// 注:最经典的用法在 if 语句条件中;
var car = new Object();
if(car){ //加入为真(存在),执行花括号里的语句
console.log("汽车"); //汽车
}
// 自动转换注意点:
1,” “ 空字符串转成数字 0;
2,[] 空数组转换数字为 0;
3,Function() 能转换成字符串”function” 转换为数字为 NaN ;
1-5-1 强制类型转换
// 1,尽管 JavaScript 可以自动进行类型转换,但有时仍需要显式转换,或者有时为了使代码变得更加清晰易读;使用 string(),number(),Boolean();
// 2,转换为数值;Number(); parseInt();parseFloat(); number() 可以用于任何类型,另外两个则专门用于把字符串转成数值,这三个函数对于同样的输入有不同的返回结果;
// 3,number()函数,转换规则如下;
1,Boolean 1,0;
2,数字 直接返回该数字;
3,undefind NaN;
4,null 0;
// 如果是字符串则遵循以下规则;
1,”123” 123;
2,“01235” 1235; // (去掉最前面的 0)
3,“1.1” 1.1 //(浮点型);
4,“01.1” 1.1 // (浮点型);
5,“0xff” 255; // (number()能识别出 16 进制);
6,“” 0;
7,“123abc” // NaN;
var value = {};
console.log(Number(value)); // NaN
var value = {};
value = {valueOf:function(){return 18}};
console.log(Number(value)); // 18
var value = {};
value = {valueOf:function(){return true}};
console.log(Number(value));
// 4,有一些操作符(+,-)的操作与 Number()函数相同,会将操作数转换为数字;
var x = "w";
console.log(typeof +x); // number (加了正负号以后把数据类型自动改了)
var x = "w";
console.log(typeof +x); //number (加了正负号以后把数据类型自动改了)
console.log(x); // "w"
console.log(+x); // NaN
1-5-2 parseInt() 函数;
// 1,number 函数在转换字符串时比较复杂而且不够合理;并且只能基于十进制进行转换,且不能出现非法的尾随字符,因此在处理整数的时候通常用的是parseInt()和 parseFloat();
// 2,二者都是全局函数,不属于任何对象的方法;
console.log(parseInt(" 8a:")); // 8;
console.log(parseInt(22.5)); // 22;
console.log(parseInt("wang1")); // NaN;
console.log(parseInt("")); //NaN
var value = "";
console.log(Number(value)); //0
console.log(parseInt(value)); //NaN
// 3,parseInt() 能识别 16 进制,识别不了字符串的 8 进制;
console.log(parseInt("0xff")); //255;
console.log(parseInt("0xafwangwei")); // 175(自动忽略除了 16 进制以外的部分)
console.log(parseInt(070)); //56;(不用字符串表示,可以识别出 8 进制并转化)
console.log(parseInt("075")); //75 (字符串里的八进制无法识别,会忽略 0 在转换为整数)
// 4,parseInt()识别八进制时,第 3 版可以识别,但第 5 版识别不了,为解决这个问题,可以为 parseInt()指定第二个参数:转换基数;
console.log(parseInt("0xff",16)); // 255 把 16 进制转换为 10 进制
console.log(parseInt("077",8)); // 63 把 8 进制转换为 10 进制
console.log(parseInt("100101",2)); // 37 把 2 进制转换为 10 进制
console.log(parseInt("054",6)); // 34 把 6 进制转换为 10 进制
// 在指定了进制以后可以把前面的 0X 或者 0 去掉了;
console.log(parseInt("ff",16));
console.log(parseInt("77",8));
console.log(parseInt("100101",2));
console.log(parseInt("54",6));
1-5-3 parseFloat() 函数;
// 1,parseFloat() 只能识别十进制,16 进制会始终转换成 0;
console.log(parseFloat("123abc")); // 123;
console.log(parseFloat("123.56abc")); // 123.56;
console.log(parseFloat("0xaa")); // 0;
console.log(parseFloat("22.5")); //22.5;
console.log(parseFloat("0909.5")); //909.5;
console.log(parseFloat("3.125e6")); //3125000;
console.log(parseFloat("0700")); //700;
7,转换为字符串
// 1,要把值转换成字符串有两种方式;第一种是使用几乎每个值都有的 toString()方法;该方法会返回相应值得字符串;
var age = 18;
var ageString = age.toString();
var found = true;
console.log(found); // ”True” 实际上调用了 found.toString()或 found.valueOf()
// 注:数值,布尔值,对象和字符串值都有 toString()方法,但 null 和 undefined值没有这个方法;
// 2. 可以为 toString()制定一个可选的基数(radix)的参数(前提是对象是数字类型),默认情况下,toString()方法以十进制格式返回数值的字符串表示;通过设置基数,可以输出其他进制的字符串;
var age = 18;
console.log(age.toString(2)); // "10010";
console.log(age.toString(8)); // "22"
console.log(age.toString(16)); // "12"
// 3,第二种方法是 String()函数,这个函数可以把任意类型的数值转换为字符串,包括 null 和 undefined;
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
// 4,如果要把某个值转换为字符串,可以使用加号操作符把他与一个空字符串拼接;
var str = 10 + "";
console.log(typeof str)
1-5-4 Boolean()类型;
// 1,使用 Boolean(),会返回一个 Boolean 值,但返回 TRUE 或者 false,取决于要转换值得数据类型及其实际值;
// 2,一元“!”运算符也将其操作数转换为布尔值并取反,这是在代码中进行这种类型转换的常用办法;
var str = "w";
console.log(!!str); //相当于 boolean(str)
1-6 检测类型
1-6-1 typeof
// 1,由于松散的数据类型,可以用 typeof 方法来检测数据类型(返回结果都是字符串);会返回一下值;
Undefined; boolean; string; number; object; null;
console.log(typeof null); // object 比较特殊,把他看成是空对象
1-6-2 instanceof
// Typeof 在检测引用类型的数据时用处不大;想要确认一个对象具体是什么类型的对象,就需要 instanceof 操作符;
var str = "w";
var o = new Object();
console.log(o instanceof Object);// true
console.log(o instanceof String); // false
console.log(str instanceof Number);// false
// 相当于判断,返回值布尔类型的;
console.log(typeof null); // object;
console.log(null instanceof Object); //false 注意区分
说明:根据规定所有引用类型的值都是 object 的实例;因此,在检测一个引用类型值和 Object 构造函数时,instanceof 操作符始终返回 TRUE;
var color = new Array();
console.log(typeof color); // object;
console.log(color instanceof Object); //true;
console.log(color instanceof Array); //true;
// 使用 instanceof 操作符在检测基本类型的值,会返回 false,因为基本类型不是对象
1-7 表达式
// 1,”wangwei”; “name”; 1.23; var; name; name; 都算一个表达式;
// 2,简单表达式(原始表达式,比如一些常量,变量) 复杂表达式(有简单表达式组合一起的表达式)
1-8 运算操作符
// 1,算数运算符:+ - * / %(取余数) ++ --;
// 2,比较运算符:== !=(不等) > >= < <= ===(全等) !==(不全等);
// 3,条件运算符:? : ;
// 4,逻辑运算符:&&(和) ||(或) ! (非);
// 5,位操作符:~ <<左移位 >>右移位 >>>无符号右移 &按位与 ^按位异或|按位或
// 6,字符元算符: + ;
// 7,赋值运算符: = += -+ *= /= %= &= ^= |= <<= >>= >>>=;
// 8,其他操作符:delete typeof void instanceof in(测试属性是否存在),逗号,忽略第一个操作数,返回第二个操作数。
1-8-1 运算符优先级
1-8-2 操作数及个数
// 1,运算符所操作的数据就是操作数,可以位于运算的左右两边或者一遍;
// 2,运算符可以根据其操作数的个数进行分类:一元操作数,如:“+”,二元操作数,如:“*”,三元操作数,如:“?”;
1-8-3 操作数类型和结果类型
有一些运算符可以作用于任何数据类型,但在真是场景中,一般都是有确定的数据类型,并且大部分运算符都会计算并返回一个特定类型的值;
1-8-4 算数运算符
console.log("1"+2); //12 (加法当中字符串中的数字不会自动类型转换)
console.log(1+{}); //1Oobject
var sum = "1" + 2;
console.log(sum); // 12
console.log(+"2" + 3); // 5
console.log(Number("3")+2) // 5
console.log(true + true); // 2
console.log(1 + true); // 2
console.log(1 + null); // 1
console.log(1 + undefined); // NaN
1,考虑到加法的结合性,既运算结果依赖于运算的顺序;
console.log(1 + 2 +"wang"); //"3wang"
console.log(1 + "wang" + 2); //"1wang2"
console.log("wang" + 2 + 1); //"wang21" (都是从左右的顺序计算);
2,连接字符串,对于 null 和 undefined,则分别调用 String()函数并取得字符串”null”和”undefined”;
console.log("wang" + null); //"wangnull"
console.log("wang" + undefined); // "wangweiundefined"
console.log("wang" + String(null)); //"wangnull"
console.log("wang" + String(undefined)); // "wangweiundefined"
3,减法:如果一个操作符是字符串,布尔值,null 或 undefined,则先在后台调用 Number()进行转换,在进行转换运算;
console.log(8 - true); // 7
console.log(8 - "true"); // NaN (注意“TRUE”引号引起来就是字符串)
console.log(8 - Number(true));
console.log(8 - null); // 8
console.log(8 - {}); // NaN
console.log(8 - "3"); // 5
console.log(8 - undefined); // NaN
console.log(Number("true")); // NaN
4,如果一个操作数是对象,数值,布尔值,则调用他们的 toString()或 valueOf()方法取得相应的字符串值,在进行计算;
console.log(8 - {toString(){return 2}}); // 6
5,其他运算
console.log(5 - true); // 4
console.log(NaN - 1); // NaN
console.log((5 - "")); // 5
console.log(5 - "2"); // 3
console.log(5 - null); // 5
console.log(-0 + 0); // 0
console.log(-0 - 0); // -0
console.log(Infinity-Infinity); //NaN
console.log(-Infinity - Infinity); //-Infinity
6,乘除操作符:如果操作数是非数值,会执行自动类型转换(既后台用 Number()函数转换),空字符串被当做 0; 其余遵循以下规则
// 1,如果计算结果超出范围 返回 Infinity -Infinity;
// 2,有一个操作数是 NaN 返回 NaN;
// 3,Infinity 与 0 相乘 返回 NaN;
// 4,Infinity 与非零相乘 返回 Infinity -Infinity;
// 5,Infinity 与 Infinity 相乘 返回 Infinity;
// 6,0 被 0 除 返回 NaN;
// 7,非零的有限数被 0 除 返回 Infinity -Infinity;
// 8,如果 Infinity 被任何非 0 除 返回 Infinity -Infinity;
console.log(5 / 0); //Infinity
console.log(-5 / 0); // -Infinity
console.log(0 / 0); //Nan
7,取模
console.log(10 % 3); // 1
console.log(6.3 % 2.1); //2.09999999999999996
// 注:小数取模会出问题;
8,一元操作符 ++ 自增 -- 自减
// 1,分为前置 ++a 后置 a++
// 2,前置操作时,变量的值都是语句被求值之前完成的(先完成变量本身自增,自减,在计算整个语句);
var age = 18;
var anotherage = --age + 2;
console.log(age); //先算 --age 再算 anotherage 17;
console.log(anotherage); // 19
// 3,后置操作时,先算整个语句再考虑变量本身的自增,自减
var age = 18;
var anotherage = age-- + 2;
console.log(age); //先算 another 再算 age-- 17;
console.log(anotherage); // 20
var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2;
console.log(num3) //先算 num3 再算 num1-- 22;
console.log(num1); // 1
// 4,包含数字的字符串会进行自动转换; ++不会进行字符串的拼接;
var x = "1";
console.log(++x); //2 也把 x 的数据类型改变了 x=2
console.log(x + 5); // x=x+5 7
var x = "1";
console.log(x + 5); // 进行字符串拼接 “15”;
console.log(++x); //2 也把 x 的数据类型改变了 x=2
5,在应用于对象时,先调用对象的 valueof 方法;如果为 NaN,则再调用toString 方法再应用;
var s1 = "2", s2 = "z" , b = false , f = 1.1 ;
o ={
valueOf:function(){
return -1;
}
}
console.log(s1++); // 2 同时 s1 变成 3;
console.log(s1); // 3
console.log(s2++); //NaN 同时把数据类型也改了;
console.log(s2); //NaN
console.log(b++); //0 同时 b 变成 1;
console.log(b);
console.log(f--); //1.1 同时 f = f-1;
console.log(f);
console.log(o--); // -1 同时 o 变成 -2;
console.log(o); //-2
6,一元加和减操作符;(可以把操作数转换成数字或 NaN)而对象先调用valueOf 和 toString 方法
var s1 = "2", s2 = "z" , b = false , f = 1.1 ;
o ={
valueOf:function(){
return -1;
}
}
console.log(+s1); // 2
console.log(+s2); //NaN
console.log(+b); //0
console.log(+f); //1.1
console.log(+o); -1
1-9 关系比较运算符
1-9-1 > < <= >=
// 1,关系运算符用于测试两个值的关系,根据他们的关系返回 TRUE 或 false;通常应用在 if,while 等控制语句中;
// 2,如果两个操作数都是字符串,则比较他们的大小;
// 3,如果一个是数值,则将另一个转换为数值,再比较;
// 4,如果一个操作数是对象,则调用 valueOf()或 toString()方法,得到结果再进行比较;
// 5,如果是布尔值,将其转换为数值再进行比较;
// 6,Infinity 比任何数字都大(除了其本身);-Infinity 比任何数都小
// 7,任何操作数与 NaN 进行比较,结果都是 false;
// 8,被认定为 false 的值:undefined,null,NaN,” ”,0,false
var o = {};
console.log(o);
o = {valueOf:function(){return 3}};
console.log(3 > 2);
console.log(3 >= 5);
console.log("a" > "b");
console.log("3" > 2);
console.log(o > 2);
console.log("a" > 5);
console.log("a" > "A");
console.log(NaN != "a"); //true
console.log(NaN > 3); //false
console.log( NaN == NaN); //false
// 9,大小写转换的方法;
console.log("abcdef".toUpperCase());
console.log("ABCDEF".toLowerCase());
1-9-2 相等和不相等 == !=
1,这两个操作数都会先转换操作数(通常称为强制转换),然后再比较;
console.log(2 == 2);
console.log(2 == 3);
console.log("w" == "w");
console.log("2" == 2); // true
console.log(true == 1);
console.log(2 != 3);
Null 和 undefined 是相等的;
console.log(null == undefined); //true
1-9-3 全等和不全等 === !==
(不进行类型转换)
console.log( "19" === 19); //false
console.log(+0 === -0); //true
var o1 = {};
var o2 = o1;
console.log(o1 === o2); //true
var x = NaN;
console.log(x !== x); //true 只有 x 等于 NaN 时才成立;
Null 和 undefined 是相等,但不是全等
console.log(null === undefined); //false
console.log(null == undefined); //true
1-9-4 条件运算符
var num1 = 10, num2 = 20
var max = num1>num2 ? num1: num2;
console.log(max); // 求绝对值;
基本语法:
// 表达式? 返回值 1:返回值 2;
// 如果表达式为真则返回 返回值 1 ,若表达式为假。则返回 返回值 2;
var x = -5;
console.log(x > 0 ? x : -x); //求绝对值;
var a = 10, b = 15;
console.log(a == b ? true:false);
判断某个变量有没有定义
var a,b;
a = "aini";
console.log(a? a:"未定义"); // "aini"
console.log(b? b:"未定义"); //"未定义"
1-10 位操作符
// 1,计算值负数:正数绝对值二进制取反 加一 如求 -18 先求 18 的二进制 10010取反以后是 01101 加一以后 01110 所以-18 二进制就等于 01110;再加一个符号位就是 101110
// 2,按位非 ~ 按位与& 按位或| 按位异或^
// 3,按位非 返回数字的反码;
var num = 25; // 25 = 11001 -25 = 00110 +00001 = 00111
var num1 = ~num; //反码 00110 所以反码是 00110 = 00111 - 00001 = -25 - 1
console.log(num1); // -26 所以反码是 00110 = 00111 - 00001 = -25 - 1 = -26
4,按位与,有两个操作符,相同位数对齐比较 全 1 出 1,有 0 出 0;
var sum = 25 & 3; // 11001
console.log(sum); // 00011 00001 = 1
5,按位或,有两个操作符,相同位数对齐比较 有 1 出 1,全 0 出 0;
var sum = 25 | 15; // 11001
console.log(sum); // 01111 11111 = 31
6,按位异或,相同返回 0,不同返回 1;
var sum = 25 ^ 15; // 11001
console.log(sum); // 01111 10110 = 22
7,c = a<<b 左移;c = a 的二进制数左移 b 位后的结果,也等于 c = a * 2^b;
var sum = 3 << 3; // 11 左移 3 位就是 11000 = 24
console.log(sum); // 24
8,c = a>>b 右移(有符号的右移>>,正数补 0,可以忽略,负数补 1,需要注意,无符号右移>>>,只会用 0 来填补);c = a 的二进制数右移移 b 位后的结果,也等于 c =a / 2^b;
var sum = 64 >> 3; // 1000000 右移 3 位就是 0001000 = 8
console.log(sum); // 8
1-11 赋值运算符
1,赋值运算符,有很低的优先级;
var a,b = 0;
console.log((a = b) == 10); //因为 = 优先级很低,一般需要用括号括起来,来提高计算的优先级
// 赋值运算符的结合性是从右到左;
var j = k = i = 0; // i=0,k=i, j=k 由于 k,i 不是用 var 声明,所以属于全局白变量;
2,如果等号前面添加了其他操作符就可以完成复合赋值操作;
+=,-=,*=,/+,%=,>>=,<<=,>>>=,&=,^=,|=
num = 10;
num+=10; //num = num + 10
console.log(num);
// += 可用于字符串
var str = "aini";
str += "&AINI";
console.log(str);
// 有时候两者有区别,指向的不是同一个元素;会出现问题
var date = [1,2,3,4];
var i = 1;
// date[i++]*=2; // date[1] = date[1]*2=4 [1,4,3,4]
date[i++] = fate[i++] *2 // [1,6,3,4] date[1] ->i=2 ->date[2] 3*2=6 最终
date[1]=date[2]*2=6
console.log(date);
1-12 其他运算符
1-12-1 typeof
两种语法 typeof value / typeof(value);
console.log(typeof 1);
console.log(typeof true);
console.log(typeof undefined);
console.log(typeof NaN);
console.log(typeof null);
console.log(typeof "aini");
console.log(typeof function(){});
1-12-2 instanceof
不能判断基本数据类型;
var num = 1;
console.log(num instanceof Number); // false 不能判断基本数据类型;
var num1 = new Number(1); // 基本包装类型
console.log(typeof num1); // object
console.log(num1 instanceof Number); //true
console.log(num1 instanceof Object);
var str = new String("aini");
console.log(typeof str); // object
console.log(str instanceof String); // true
console.log(str instanceof Object); // true
var colors = new Array();
console.log(typeof colors);
console.log(colors instanceof Array);
console.log(colors instanceof Object);
1-12-3 in 运算符
in 运算符希望它的操作数是一个字符或者可以转换为字符,右操作数是一个对象;如果该对象拥有一个名为左操作符的属性名,则表示返回 TRUE;
var point = {x:1,y:1};
console.log(1 in point); // false
console.log("x" in point); // true
console.log("z" in point); // false
console.log("toString" in point); //True 所有对象都继承了 Object 的 toString 方法
var date =[1,2,3];
console.log("0" in date); // 能自动转换
console.log(1 in date); // 判断索引
console.log(3 in date); // false
1-12-4 delete 运算符
能删除对象的方法和属性;
var point = {x:1,y:1};
delete point.x;
console.log(point); // {y: 1}
var date =[1,2,3];
delete date[1];
console.log(date); // (3) [1, 空, 3]
1-12-5 逗号运算符
1,一次性声明多个变量需要逗号隔开;
2,逗号运算符在一条语句中执行多个操作;在用于赋值的时候,逗号操作符总会返回表达式中的最后一项;
var a = (1,3,5,7,9);
console.log(a); // 9
3,其首先计算左操作数,再计算右操作数,最后返回右操作数的值;
var num = (i =2 , j =3, k =i+j);
console.log(num); //5
2,流程控制
2-1 前言
1,表达式语句
// 1,具有副作用的表达式是js中最简单的语句;如赋值语句str = “zero” + “network”;
// 2,递增递减运算也是一种表达式;
// 3,Delete 运算符非作用是删除一个对象的属性,所以他也是语句,而不是表达式;
// 4,函数调用是表达式语句中的另一个大类;
3 + 2; //表达式
a = 2; // 语句
alert("wangwei"); //语句
console.log(x = Math.cos(60)); //语句
2 复合语句和空语句
复合语句和空语句,可以把多条语句联合在一起,形成一条复合语句;使用花括号将多条语句括起来,也称为代码块;
{
var x = Math.PI;
var cs = Math.cos(x);
console.log("cos(PI) = " + cs);
}
// 注:语句块结尾不需要分号;
空语句:允许包含 0 条语句的语句,其实用分号;表示;Js 解释器在执行空语句时不会执行任何动作,但某些情况下,空语句还是很有用的;
var a =[];
for(var i = 0 ;i < 10;a[i++]=i);
console.log(a);
3,声明语句 var function 4,顺序结构 ES 程序就是一些列可执行语句的集合;默认情况下,JS 解析器依照语句的编写顺序依次执行,这是程序最基本的结构; 5,流程控制结构 : 流程就是代码执行顺序,流程控制就是改变语句的默认执行顺序,使其按一定的方式进行; 1,条件(condition) 语句 2,循环语句(loop) 3,跳转语句(jump) 如 break,return,throw 语句
2-2 条件语句
2-2-1 if 条件
2-1-1 形式一
if(condition) statement;
var a = 10;
if(a == 10) console.log("a is 10");
if("wangwei") console.log("aini is a good person"); //只要是个真值就行
ES 语法规定,if 关键字和带圆括号的表达式之后必须跟随一条语句,但只能是一条语句,可以分行写,也可以写在一起;如果有多条,可以使用语句块;
var a = 10;
if(a != 10){
console.log(a);
console.log(a + 10);
}
注:一般使用 Xnull 或 Xundefined 或简写!X 来判断一个变量是否有效;
var x;
if(!x) x = 12; //如果 x 没有值的话
console.log(x);
2-1-2 x形式二
if else 语句 if(condition)statement1;else tatement2;
多条语句加花括号; 同?:一样
var x = 10;
var y = 15;
if(x == 10){
console.log("x = 10")
}else{
console.log("x != 10")
}
if(y==10) console.log("y = 10")
else console.log("y != 10");
2-1-3 形式三
if-else if 语句 多条件语句
var grade = 41;
if (grade>=80 & grade<=100)
console.log("良好");
else if(grade>=60)
console.log("及格");
else if(grade>=40)
console.log("不及格");
else
console.log("0");
2-1-4 if 语句嵌套
var a = 30;
if(a >= 0 & a<=10){
if(a>=0 & a<=5){
console.log("a 在 5 之内");
}else{
console.log("a 在 6 到 10 之内");
}
}else if(a >10 & a<=20){
if(a>10 & a<=15){
console.log("a 在 11 到 15 之内");
}else{
console.log("a 在 16 到 20 之内");
}
}else{
console.log("a 大于 20");
}
2-2-2 Switch 语句
// 语法:
Switch(expression){
Case value 1:statement ;
break;
case value 2: statement;
break;
default :statement;
}
var n = 2;
switch(n){
case 1:
console.log(1);
break;
case 2:
console.log(2);
break;
case 3:
console.log(3);
break;
case 4:
console.log(4);
break;
default:
console.log("other");
// 本质来讲,case只是指明了程序运行的起点,只要找到复合的case语句,就开始进行,直到程序结束
// 每一个case语句里加break;不然找到了第一个匹配的值以后就会继续往下算,直到程序结束
// Default 是当所有case不匹配时才运行,一般放到最后面
var n = 2;
switch(true){
case n > 0:
console.log("大于0");
break;
case n = 0:
console.log("等于0");
break;
case n < 0:
console.log("小于0");
break;
}
// 如果把所有可能性已经囊括了,就不需要写default
// Case后:具体的一个值,运算,返回,常量,变量
// Case语句在比较值是用的是全等操作符,因此不会进行类型转换;所以字符串”10”不等
var n = 1;
switch(n){
case 1:
case 2:
console.log(2);
break;
case 3:
console.log(3);
case 4:
console.log(4);
break;
}
如果在函数中使用Switch,可以使用return代替break,两者都用于终止Switch语句,也会防止一个case语句块执行完后继续执行下一个case语句块;
function convert(x){
switch(typeof x){
case 'number':
return x.toString(16);
case 'string':
return '"' + x +'"';
default:
return "other";
}
}
console.log(convert(18));
console.log(convert("aini"));
console.log(convert(true));
// Return会返回值并直接退出函数
var str = "world";
switch("hello world"){
case str:
console.log(str);
break;
case "world":
console.log("world");
break;
case "hello " + str:
console.log("hello " + str);
break;
default:
console.log("other");
}
switch(true){
case "wangwei": //这是真值,但不是布尔的TRUE,也不会进行自动转换,所以不成立
console.log("wangwei");
break;
case 1:
console.log(1);
break;
case 3 > 2: //返回的结果是 TRUE ,所以会运行case 3 > 2的情况
console.log(true);
break;
default:
console.log("other");
}
var str = "10";
switch(str){
case 10:
console.log("这是数字10");
braak;
case "10":
console.log("这是字符串10");
break;
}
// Case语句在比较值是用的是全等操作符,因此不会进行类型转换;所以字符串”10”不等于数字10
Case 后面建议使用常量,避免使用副作用的表达式
3,循环控制
3-1 while 循环
1,属于前测试循环语句,循环之前判断条件是否成立;
2,语法 while(expression){statement:}
var count = 0;
while(count < 10){
console.log(count);
count++;
};
var count = 0;
var sum = 0;
while(count <= 100){
sum += count
count++;
};
console.log(sum);
// while语句里的分号建议加上
var i = 18;
while(true){
console.log(i)
if(i == 18){
break;
}
}
// break语句能结束while循环,跳出循环;有时候为了避免死循环,可以使用
3-2 Do while 循环
1,后测试循环,先执行一遍循环,再判断条件是否满足,所以循环至少执行一次;
var i = 0;
do{
i+=2;
}while(i<=10)
console.log(i);
// 也可以这样用,改变条件的表达式直接写在
var i = 0;
do{
console.log(i);
}while((i+=2) < 10);
// 这样可以先改变条件,再进行循环;相当于前测试循环
function printArray(arr){
var len = arr.length,i=0;
if(len == 0){
console.log("Emprty Array")
}else{
do{
console.log(arr[i]);
}while(++i < len);
}
}
var arr=["beijing","nanjing","xinjiang","gaungdong"];
printArray(arr);
<body>
<div id="mydiv"></div>
<script>
var imgArr = ["xm/1.webp","xm/2.webp","xm/3.webp","xm/4.webp","xm/5.webp","xm/6.webp","xm/7.webp","xm/8.webp",];
var mydiv = document.getElementById("mydiv");
var i = 0;
while(i < imgArr.length){
var img = document.createElement("img");
img.src = imgArr[i];
mydiv.appendChild(img);
i++;
}
</script>
</body>
3-3 for 循环
1,前测试循环语句;已知循环次数情况下使用for循环比较合适;
2,语法 for(初始循环变量;test条件表达式 ;增量表达式){statement}
3,初始循环变量只是循环开始时执行一次
for(var i = 0; i < 10; i++){
console.log(i);
}
// 跟上面的for循环等价
var i = 0;
while(i < 10){
console.log(i);
i++;
}
var count = 0;
while(count++,count < 10){
console.log(count);
}
// 注:不能把初始化变量放到while括号里面;但是可以放不影响增量的其他变量;
// 从左往右计算,返回逗号运算符最右侧的代码
var result = 1,i = 1;
while(i <=8){
result*=i;
console.log(i + "的阶乘是: " + result);
i++;
};
简化上面的while循环
var result = 1,i = 1;
while(result*=i, i++,i <=8){
console.log(i + "的阶乘是: " + result);
};
var result = 1;
for(var i = 1; i <= 8; i++){
result*=i;
console.log(i + "的阶乘是: " + result);
}
var count = 10,i;
for(i=0;i<count;i++)
console.log(i);
// i可以在外部定义,for循环里面就不用定
var count = 10,i=0;
for(;i<count;i++)
console.log(i);
// For循环中,初始化变量,条件表达式,增量表达式都是可选的,但是分号不能省略
var count = 10,i=0;
for(;;i++)
if(i<count){
console.log(i);
}else{
break;
}
// 这是一个死循环
var count = 10,i=0;
for(;;)
console.log(i);
把初始化放到外部,把条件表达式以及更新表达式放到内部,条件不满足使用break跳出循环
var count = 10,i=0;
for(;i<count;){
console.log(i);
i++;
}
// 所以可以把初始化和增量放到外部
可以有多个初始化变量,条件表达式,增量表达式,需要用逗号运算符
var sum = 0;
for(var i=0,j=1;i<10;i++,j++){
sum+= i*j;
console.log(i + "," + j);
}
console.log(sum);
For循环的执行顺序
for(var i=0,j=console.log("A");console.log("B"),i<10;console.log("C"), i++){
console.log("aini");
}
// 顺序:
i=0,j=console.log("A") console.log("B"),i<10 console.log("aini") console.log("C"), i++ console.log("B"),i<10 console.log("aini") console.log("C"), i++
总之:初始变量语句只运行一次,增量表达式在statement以后再执行
for(var i=0,j=1;i<10;i++,j++){
document.write(i);
if(j%4==0){
document.write("</br>");
}
}
3-4 for-in 循环
1,for in 是精准的迭代语句;
2,语法 for(variable in object){statement}
for(var proname in window){
console.log(proname);
}
// window是一个内置对象,for in可以把内置对象的所有属性,方法,事件枚举出来
var arr=[];
for(var i=0;i<10;i++){
arr[i]=i*10;
}
for(var j=0;j<arr.length;j++){
console.log(arr[j]);
}
for(var k in arr){
console.log("数组中的第" + k + "个元素是: " + arr[k]);
}
// 把数组中的元素枚举出来,可以用for循环,也可以用for-in语句
// For-in来枚举数组索引
var str ="hello world";
for(var a in str){
console.log(a + "字符:" + str[a]);
}
// 字符串也可以像数组一样枚举出来
var person = {
name:"aini",
age:18,
walk:function(){
console.log("aini can walk")
}
}
for(var p in person){
console.log(p + ": " +person[p]);
}
// 可以把对象的属性和属性值枚举出来
// 注:P是属性,person[p]才是属性值数组里面也是同理,索引和值
ESMAScript对象的属性没有顺序,因此用for-in循环出来的属性名的顺序不可预测;如果迭代的对象时null或undefined,ES5之前会抛出错误,在ES5里面不会报错误,也不执行如果object表达式等于一个原始值,这个原始值会转换为与之对应的包装对象;
var num = 18;
for(var n in num){
console.log(n);
}
var str ="hello world";
for(var a in str){ //这里使用了new String(str) 把原始类型转换为基本包装类型;
console.log(a);
}
ar person = {
name:"aini",
age:18,
walk:function(){
console.log("aini can walk")
}
}
var a =[],i=0;
for(a[i++] in person);
console.log(a);
// A[i++]在这里既可以当变量,也可以自增,同时对自己赋值
For- in并不会遍历所有的属性和方法,只会枚举可枚举的属性和方法,由js核心语言内置的属性和方法就是不可枚举的,比如toString(),valueOf();
各种循环可以任意嵌套
3-5 跳转
1,可以从一个位置跳转到另一个位置;
2,标签语句:任何语句如果在前面加上标识符和冒号都可以构成标签语句,以便将来使用;
语法: label:statement
var flag = true;
one:
if(flag){
console.log("flag");
}
start:
for(var i=0; i<10;i++){
console.log(i);
}
two:
{
var num =18;
num++
console.log(num);
}
// 一般与for,while语句配合使用;既在循环体内使用break和continue退出或跳转到标签外,二者是唯一可以使用标签的语句;
// 标签可以跟变量函数名同名;
// 标签可以嵌套
// 嵌套时标签名不允许跟标签名重复
one: for(var i = 0;i<5; i++){
two: for(var j = 0; j<5;j++){
console.log(i+j);
}
}
// 嵌套里的标签不允许
// 单独使用break语句可以立即退出最内层的循环或者Switch语句(break语句只能用在循环或者Switch中)
// reak与标签语句配合使用,退出这个循环的同时跳转到标签处结尾处,可以用于跳出多层循环的
var num = 0;
outermost:
for(var i = 0;i < 10;i++){
for(var j = 0; j < 10;j++){
if(j==5){
break outermost;
}
console.log(i + "," +j);
num++;
}
}
console.log(num);
var num = 0;
outermost:
for(var i = 0;i < 10;i++){
inner: for(var j = 0; j < 10;j++){
if(j==5){
break;
}
console.log(i + "," +j);
num++;
}
for(var k = 0;k<5;k++){
if(k==2){
break inner;
}
}
}
console.log(num);
var sumarr = [[1,2,3],[2,"a",4],[4,5,6]],sum = 0;
compute_sum:
if(sumarr){
for(var i=0;i<sumarr.length;i++){
var row = sumarr[i];
if(!Array.isArray(row)){
break compute_sum;
}
for(var y = 0; y < row.length; y++){
var cell = row[y]
if(isNaN(cell)){
break compute_sum;
}
sum+=cell;
}
}
console.log("全部执行完毕");
}
console.log(sum);
3-6 continue 语句
// Continue语句与break语句非常相似,区别在于他不在退出循环,而是结束本次循环,继续下次循环,其与break用法基本一致
// Continue只能用在循环体当中
for(var i = 0;i<5; i++){
if(i == 3) continue;
console.log(i);
}
// 遇到3结束本次循环,开始下次
var date = [1,2,undefined,4,NaN,8,9,null]; sum = 0,error = 0;
for(var i = 0; i<date.length;i++){
if(!date[i]){
error+=1;
continue;
}
sum+=date[i];
}
console.log(sum);
console.log(error);
// Continue可以与标签配合使用,就是跳出外侧循环,继续进行外侧循环的下一次循环
3-7 return 语句
// Return语句只能在函数中使用,既函数调用后的返回值;
// 如果没有return语句,则程序返回的结果就是undefined
// Return默认返回值也是undefined
function display_object(o){
if(!o) return ;
for(p in o){
console.log(p);
}
return;
}
var person ={
name:"aini",
age:18,
city:"xinjiang"
}
console.log( display_object(person)) ;
3-8 with 语句
// 为了简写代码
With(object){statement}
var person = {
name:"aini",
age:18,
city:"xinjiagn"
}
console.log(person.name);
console.log(person.age);
console.log(person.city);
// 可以这样简写代码
with(person){
console.log(name);
console.log(age);
console.log(city);
}
3-9 Debugger语句
// 什么也不做,用于调试,不怎么重要,会在debugger语句的地方产生一个断点
3-10 “use strict” 语句
// 让js代码在严格模式下执行
4,函数
4-1 定义函数
4-1-1 第一种方式
// 第一种方法:函数声明式,关键字function定义;
4-1-2 第二种方式
// 第二种方法:function实际上也是对象,所以可以使用function对象的构造函数来创建一个函数;
// Var 变量名 = new Function(形参1,形参2,代码体);
var date ="var num =prompt('input');console.log(num);"
var date1 ="alert('aini');"
var date2 ="var p=fname:'aini',age:19};console.log(p.name)";
var fun =new Function(date2);
fun();
var scope ="global";|
function func(){
var scope ="local";
var myFun =new Function("return scope;");
console.log(myFun());
}
func();
// 注:只能认全局变量,在函数中的局部变量识别不了;所以上述例子返回“global”;内部的“local”识别不了;
// 注:1,参数,代码体必须使用引号引起来,代码体放在最后一个引号里,语句和语句之间分号引起来;
// 2,如果没有参数则省略,只有代码体的引号;
4-1-3 第三种方式
可以直接把定义函数保存在变量中,该变量名实际上就是函数
// Var 变量名 = function(参数1,参数2){表达式语句}
var mysum =function(num1,num2){return num1+num2;
console.log(mysum(10,20));
由于函数名仅仅是函数的指针,所以可以把函数名赋值给多个变量,这么说一个函数可以有多个名字
<script>
function sum(num1,num2){
return num1 +num2;
}
mysum =sum;
anothersom =sum;
console.log(mysum(10,20));
console.log(anothersom(30,50));
</script>
把函数名赋值的时候不能带括号,带括号的话立马就执行了
<script>
var sayworld;
var condition =false;
if(condition){
sayworld =function(){console.log("aini")};
}else{
sayworld =Function()fconsole.1og("AINI")};
}
sayworld();
</script>
函数声明和函数表达式的区别
// 解释器在执行环境中加载数据时,会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于表达式,则必须等解析器执行到它所在的代码行,才会真正被解析;
sayHi();
function sayHi(){
console.log("hi");
}
// Function函数声明的时候,访问可以放在函数之前,也可以放在函数后面
sayHi();
var sayhi =function(){console.log("Hi");
// 通过表达式定义的函数,访问必须在定义之后,不然会出错
4-1-4 定义函数的三种方式
// 1,函数声明;
// 2,利用Function类构造函数;
// 3,通过函数表达式构造函数
// 函数的调用:可以在代码中调用,也可以在事件中调用,还可以通过链接调用;
<script>
function sum(a,b){
return a+b;
}
console.log(sum(10,20));
var sum1 =function(a,b){
return a +b;
}
console.log(sum1(20,30));
var fun =new Function("a","b","return a+b");
console.log(fun(50,100));
</script>
// 1,如果调用函数时输入的实参的个数大于形参的个数,则忽略多余的实参;
// 2,实参的个数小于形参,则没有接受传递值得参数赋予undefined;
// Return返回值:只要执行带return就会返回,并退出,后面的代码永远不会执行;return只能用在函数当中
// Return 也可以不带任何返回值,在这种情况下函数就会停止运行并返回undefined
// 函数中不用return也会返回undefined