javascript基础

1.引入方式

引入方式分为行内和外部引入,浏览器会同步解析(没有设置async/defer)。
< script >标签属性:

  • async : 表示应该立即下载脚本,不阻塞页面,对外部脚本有效。
  • defer : 表示脚本可以延迟到文档完全被解析和显示之后再执行(触发 DOMContentLoaded 事件前执行),对外部脚本有效。
  • charset : 使用src属性指定的代码字符集。
  • crossorigin : 配置相关请求的CROS设置。"anonymous"不设置凭据标志,"use-credentials"设置凭据标志。
  • integrity : 允许比对接受的资源和指定的加密签名以验证子资源完整性。
  • nomodule : 标明这个脚本在支持 ES2015 modules 的浏览器中不执行。
  • src : 表示包含要执行代码的外部文件。
  • type : 表示代码块中脚本语言的内容类型。支持的MIME类型包括text/javascript, text/ecmascript, application/javascript, 和application/ecmascript。如果type属性为module,代码会被当作es6模块 。

< noscript >标签在浏览器不支持脚本或浏览器对脚本的支持被关闭时显示标签里的内容。

2.变量定义

标识符:第一个字符必须是字母,下划线( _ )或美元符号( $ ),剩下的其他字符可以是字母,下划线,美元符号或数字

  • var:申明变量的范围是函数作用域,声明自动提升到函数作用域顶部,可以重复声明。在全局作用域中声明的变量会成为window对象的属性。去掉var关键字声明的变量是全局变量。
  • let:申明变量的范围是块作用域,不存在变量提升,不可以重复声明。在全局作用域中声明的变量不会成为window对象的属性。
  • const:与let基本相同,声明变量时必须同时初始化变量且不能修改。
function test(){
	console.log(message);//undefined
	var message='Hi';
	name='Tom';
}
test();
console.log(name); //"Tom"
console.log(window.name); //"Tom"
console.log(message); //报错:Uncaught ReferenceError: message is not defined

var age=11;
let sex='man';

console.log(window.age);//11
console.log(window.sex);//undefined

3.数据类型

typeof操作符会放回下列字符串之一

  1. "undefined"表示值未定义
  2. "boolean"表示值为布尔值
  3. "string"表示值为字符串
  4. "number"表示值为数值
  5. "object"表示值为对象(而不是函数)或null
  6. "function"表示值为函数
  7. "symbol"表示值为符号
  • Undefined类型
    Undefined类型只有一个undefined值。使用var或let声明了变量但没有初始值,相当于给变量赋予了undefined值。
  • Null类型
    Null类型也只有一个null值。null表示一个空对象指针,在定义将来要保存对象值得的变量时,建议使用null来初始化。
  • Boolean类型
    Boolean类型有2个字面值:true和false。
    Boolean()转型函数可以在任意类型上使用,转换规则见下表:
数据类型truefalse
Booleantruefalse
String非空字符串“”(空字符串)
Number非零数值(包括无穷值)0 , NaN
Object任意对象null
Undefined不存在undefined
  • Number类型

1.整数

let intNum=55;//十进制整数

let octalNum1=070;//八进制的56
let octalNum1=079;//无效八进制,当成79处理

let hexNum1=0xA;//十六进制10

2.浮点数

let floatNum1=1.1;
let floatNum2=0.1;
let floatNum3=.1;//不推荐
let floatNum4=1.;//小数点后没数字,当成整数1处理
let floatNum5=10.0;//小数点后面是零,当成整数10处理
let floatNum6=3.125e+7;//等于31250000

3.值的范围
ECMAScript可以表示的最小数值保存在Number.MIN_VALUE中,多数浏览器中是5e-324,最大数值保存在Number.MAX_VALUE中,多数浏览器中是1.797693134862315e+308,任何无法表示的负数以-Infinity表示,任何无法表示的正数以Infinity表示。
4.NaN
NaN意思是“不是数值”,表示本来要返回数值的操作失败了(而不是抛出错误)。
NaN不等于包括NaN在内的任何值。

console.log(0/0);//NaN
console.log(-0/+0);//NaN
console.log(5/0);//Infinity
console.log(5/-0);//-Infinity
console.log(NaN==NaN);//false

console.log(isNaN(NaN));//true
console.log(isNaN(10));//false
console.log(isNaN("10"));//false
console.log(isNaN("blue"));//true
console.log(isNaN(true));//false

5.数值转换
Number()函数转换规则:
1.布尔值,true转换为1,false转换为0。
2.数值,直接返回。
3.null,返回0。
4.undefined,返回NaN。
5.字符串,如果字符串包含数值字符,包括前面带+,-的情况,则转换为一个十进制数值。如果包含有效的浮点值,则转换为相应的浮点值。如果包含有效的十六进制格式,则转换为该十六进制对应的十进制整数值。如果是空字符串,则返回0。如果包含除上述情况之外的其他字符,则返回NaN。
parseInt()函数更关注字符串是否包含数值模式。字符串前面的空格会被忽略,如果第一个字符不是数值,+或-,返回NaN。否则继续检测,直至字符串末尾,或碰到非数值字符。
parseFloat()函数工作方式与parseInt()函数类似,不同之处在于始终忽略字符串开头的零。

Number("hello word");//NaN
Number("");//0
Number("000011");//11
Number(true);//1

parseInt("1234blue");//1234
parseInt("");//NaN
parseInt("0xA");//10
parseInt("22.5");//22
parseInt("70");70
parseInt("0xAF",16);//175
parseInt("AF",16);//175
parseInt("AF");//NaN

parseFloat("1234blue");//1234
parseFloat("0xA");//0
parseFloat("22.5");//22.5
parseFloat("22.34.5");//22.34
parseFloat("0908.5");908.5
parseFloat("3.125e7");//31250000
  • String类型

1.字符字面量

字面量含义
\n换行
\t制表
\b退格
\r回车
\f换页
\ \反斜杠
\ ‘单引号
\ "双引号
\ `反引号
\xnn以十六进制编码nn表示的字符
\unnnn以十六进制编码nnnn表示的Unicode字符

2.转换为字符串
toString()方法可见与数值,布尔值,对象和字符串,null和undefined没有toString()方法。
String()转型函数规则:
1.如果值有toString()方法,则调用该方法并返回结果。
2.如果值是null,则返回"null"。
3.如果值是undefined,则返回"undefined"。

let num=10;
console.log(num.toString());//"10"
console.log(num.toString(2));//"1010"
console.log(num.toString(8));//"12"
console.log(num.toString(10));//"10"
console.log(num.toString(16));//"a"

let v1=10;
let v2=true;
let v3=null;
let v4;
console.log(String(v1));//"10";
console.log(String(v2));//"true"
console.log(String(v3));//"null"
console.log(String(v4));//"undefined"

4.模板字面量
字符串插值会使用toString()强制转型为字符串。

let num1=3;
let num2=5;
console.log(`${num1} + ${num2} = ${num1+num2}`);//3 + 5 = 8

//标签函数
function simpleTag(strings,...expressions){
	console.log(strings);//[""," + "," = ",""]
	return strings[0] + expressions.map((e,i) => `${e}${strings[i+1]}`).join('');
}
console.log(simpleTag`${num1} + ${num2} = ${num1+num2}`);//3 + 5 = 8

5.原始字符串
String.raw标签函数用于获取原始的模板字面量内容(如换行符或Unicode字符)。

console.log(`\u00A9`);//©
console.log(String.raw`\u00A9`);//\u00A9
console.log(String.raw`2+3=\n${2+3}`);//1 2+3=\n5
console.log(String.raw({
	raw:['','+','=','']
},2,3,5));//2+3=5
  • Symbol类型
    符号是原始值,且符号实例唯一,不可变的。
    1.基本用法
let s1=Symbol('foo');
let s2=Symbol('foo');
console.log(s1==s2);//false

//全局符号注册表
let s3=Symbol.for('foo');
let s4=Symbol.for('foo');
console.log(s3===s4);//true
console.log(Symbol.keyFor(s3));//foo
console.log(Symbol.keyFor(s1));//undefined

//使用符号作属性
let o={
	[s1]:'s1',
	[s2]:'s2',
	[s3]:'s3'
}
console.log(o[s1],o[s2],o[s3]);//s1 s2 s3

2.内置符号

  1. Symbol.asyncIterator
    一个方法,该方法返回对象默认的AsyncIterator。由for-await-of语句使用。
class Emitter{
	constructor(max){
		this.max=max;
		this.asyncIdx=0;
	}
	async *[Symbol.asyncIterator](){
		while(this.asyncIdx<this.max){
			yield new Promise((resolve) =>{
				setTimeout(() =>resolve(this.asyncIdx++),1000)
			})
		}
	}
}
let emitter=new Emitter(5);
for await(const x of emitter){
	console.log(x);
}
//0 1 2 3 4 每隔1s打印一个
  1. Symbol.iterator
    一个方法,该方法返回对象默认的迭代器。由for-of语句使用。
class Emitter{
	constructor(max){
		this.max=max;
		this.idx=0;
	}
	*[Symbol.iterator](){
		while(this.idx<this.max){
			yield this.idx++;
		}
	}
}
let emitter=new Emitter(5);
for(const x of emitter){
	console.log(x);
}
//0 1 2 3 4
  1. Symbol.hasInstance
    一个方法,该方法决定一个构造对象是否认可一个对象是它的实例。由instanceof操作符使用。
class Bar{}
class Baz extends Bar{
	static [Symbol.hasInstance](){
		return false;
	}
}
let b=new Baz();
console.log(b instanceof Bar);//true
console.log(Bar[Symbol.hasInstance](b));//true
console.log(b instanceof Baz);//false
console.log(Baz[Symbol.hasInstance](b));//false
  1. Symbol.isConcatSpreadable
    一个布尔值,如果是true,则意味着对象应该用Array.prototype.concat()打平其数组元素。数组对象默认情况下会被打平到已有数组,false或假值会导致整个对象被追加到数组末尾。类数组对象默认情况下会被追加到数组末尾,true或真值会导致这个类数组对象被打平到数组实例。其他不是类数组对象的对象在Symbol.isConcatSpreadable被设置为true的情况下将被忽略。
let initial=['foo'];
let array=['bar'];
console.log(array[Symbol.isConcatSpreadable]);//undefined
console.log(initial.concat(array));//["foo", "bar"]
array[Symbol.isConcatSpreadable]=false;
console.log(initial.concat(array));//["foo", ["bar"]]

let arrayLikeObject={0:'baz',length:1};
console.log(arrayLikeObject[Symbol.isConcatSpreadable]);//undefined
console.log(initial.concat(arrayLikeObject));//["foo", {...}]
arrayLikeObject[Symbol.isConcatSpreadable]=true;
console.log(initial.concat(arrayLikeObject));//["foo", "baz"]

let otherObject={a:'a'};
console.log(otherObject[Symbol.isConcatSpreadable]);//undefined
console.log(initial.concat(otherObject));//["foo", {...}]
otherObject[Symbol.isConcatSpreadable]=true;
console.log(initial.concat(otherObject));//["foo"]
  1. Symbol.match
    一个正则表达式方法,该方法用正则表达式去匹配字符串。由String.prototype.match()方法使用。
class FooMatcher{
	static [Symbol.match](target){
		return target.includes('foo');
	}
}
console.log('foobar'.match(FooMatcher));//true
console.log('barbaz'.match(FooMatcher));//false

class StringMatcher{
	constructor(str){
		this.str=str;
	}
	[Symbol.match](target){
		return target.includes(this.str);
	}
}
console.log('foobar'.match(new StringMatcher('foo')));//true
console.log('barbaz'.match(new StringMatcher('qux')));//false
  1. Symbol.replace
    一个正则表达式方法,该方法替换一个字符串中匹配的子串。由String.prototype.replace()方法使用。
class FooReplacer{
	static [Symbol.replace](target,replacement){
		return target.split('foo').join(replacement);
	}
}
console.log('foobarbaz'.replace(FooReplacer,'qux'));//quxbarbaz

class StringReplacer{
	constructor(str){
		this.str=str;
	}
	[Symbol.replace](target,replacement){
		return target.split(this.str).join(replacement);
	}
}
console.log('foobarbaz'.replace(new StringReplacer('bar'),'qux'));//fooquxbaz
  1. Symbol.search
    一个正则表达式方法,该方法返回字符串中匹配正则表达式的索引。由String.prototype.search()方法使用。
class FooSearch{
	static [Symbol.search](target){
		return target.indexOf('foo');
	}
}
console.log('foobarbaz'.search(FooSearch));//0

class StringSearch{
	constructor(str){
		this.str=str;
	}
	[Symbol.search](target){
		return target.indexOf(this.str);
	}
}
console.log('foobarbaz'.search(new StringSearch('bar')));//3
  1. Symbol.species
    一个函数值,该函数作为创建派生对象的构造函数。
class Bar extends Array{}
class Baz extends Array{
	static get [Symbol.species](){
		return Array;
	}
}
let bar=new Bar();
console.log(bar instanceof Array);//true
console.log(bar instanceof Bar );//true
bar=bar.concat('bar');
console.log(bar instanceof Array);//true
console.log(bar instanceof Bar );//true
let baz=new Baz();
console.log(baz instanceof Array);//true
console.log(baz instanceof Baz);//true
baz=baz.concat('bar');
console.log(baz instanceof Array);//true
console.log(baz instanceof Baz);//false
  1. Symbol.split
    一个正则表达式方法,该方法在匹配正则表达式的索引位置拆分字符串。由String.prototype.split()方法使用。
class FooSplitter{
	static [Symbol.split](target){
		return target.split('foo');
	}
}
console.log('barfoobaz'.split(FooSplitter));//["foo","baz"]
  1. Symbol.toPrimitive
    一个方法,该方法将对象转换为相应的原始值。由ToPrimitive抽象操作使用。
class Foo{}
let foo=new Foo();
console.log(3+foo);//"3[Object Object]"
console.log(3-foo);//NaN
console.log(String(foo));//"[Object Object]"

class Bar{
	[Symbol.toPrimitive](hint){
		switch(hint){
			case "number":
				return 3;
			case "string":
				return "string bar";
			case "default":
			default:
				return "default bar";
		}
	}
}
let bar=new Bar();
console.log(3+bar);//"3default bar"
console.log(3-bar);//0
console.log(String(bar));//"string bar"
  1. Symbol.toStringTag
    一个字符串,该字符串用于创建对象的默认字符串描述。由内置方法Object.prototype.toString()使用。
let s=new Set();
console.log(s);//Set(0){}
console.log(s.toString());//[Object Set]
console.log(s[Symbol.toStringTag]);//Set

class Foo{}
let foo=new Foo();
console.log(foo);//Foo{}
console.log(foo.toString());//[Object Object ]
console.log(foo[Symbol.toStringTag]);//undefined

class Bar{
	constructor(){
		this[Symbol.toStringTag]="Bar"
	}
}
let bar=new Bar();
console.log(bar);//Foo{}
console.log(bar.toString());//[Object Bar]
console.log(bar[Symbol.toStringTag]);//Bar
  1. Symbol.unscopables
    一个对象,该对象所有的以及继承的属性,都会从关联对象的with环境绑定中移除。
let o={foo:"bar"};
with(o){
	console.log(foo);//bar
}

o[Symbol.unscopables]={
	foo:true
}
with(o){
	console.log(foo);//Uncaught ReferenceError: foo is not defined
}
  1. Object类型
    每个Object实例都有如下属性和方法。
  2. constructor:用于创建当前对象的函数。
  3. hasOwnProperty(propertyName):用于判断当前实例(不是原型)上是否存在给定的属性。
  4. isPrototypeOf(object):用于判断当前对象是否为另一个对象的原型。
  5. propertyIsEnumerable(propertyName):用于判断给定属性是否可以使用for-in语句枚举。
  6. toLocaleString():返回对象的本地化字符串。
  7. toString():返回对象的字符串表示。
  8. valueOf():返回对象对应的字符串,数值或布尔值表示。
let o=new Object();
let o=new Object;//没有参数可省略括号,不推荐

4.操作符

  1. 一元操作符

1.递增/递减

let num1=2;
let num2=20;
let num3=--num1 +num2;
let num4=num1+num2;
let num5=num1++ +num2;
let num6=num1+num2;

console.log(num3);//21
console.log(num4);//21
console.log(num5);//21
console.log(num6);//22

/**递增/递减操作符应用规则:
1.对于字符串,如果是有效数值,则转换为数值再应用。如果不是有效数值,则将变量的值设为NaN。
2.对于布尔值,如果是true,则转换为1。如果是false,则转换为0。
3.对于浮点值,加1或减1。
4.对于对象,则调用valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是NaN,则调用toString()并再次应用其他规则。
**/
let s1="2";
let s2="z";
let b=false;
let f=1.1;
let o={
	valueOf(){
		return -1;
	}
}
console.log(++s1);//3
console.log(++s2);//NaN
console.log(++b);//1
console.log(--f);//0.10000000000000009
console.log(--o);//-2

2.一元加和减

/**
应用到非数值,则会执行与使用Number()转型函数一样的类型转换:
布尔值false和true转换为0和1,字符串根据特殊规则解析,对象会调用他们的valueOf()或toString()方法以得到可以转换的值。
**/
let s1="01";
let s2="1.1";
let s3="z";
let b=false;
let f=1.1;
let o={
	valueOf(){
		return -1;
	}
}
console.log(+s1);//1
console.log(+s2);//1.1
console.log(+s3);//NaN
console.log(-b);//-0
console.log(-f);//-1.1
console.log(-o);//1
  1. 位操作符
/**
按位非(~):它的作用是返回数值的一补数。
按位与(&):按位与操作在两个位都是1时返回1,在任何一位是0时返回0。
按位或(|):按位或操作在至少一位是1时返回1,两位都是0时返回0。
按位异或(^):它只在一位上是1时返回1,两为都是0或1时返回0。
左移(<<):会按照指定的位数将数值的所有位向左移动。
有符号右移(>>):会将数值的所有32位都向右移,同时保留符号(正或负)。
无符号右移(>>>):会将数值的所有32位都向右移
25 :1*2^4+1*2^3+0*2^2+0*2^1+1*2^0
0000 0000 0000 0000 0000 0000 0001 1001
3 :1*2^1+1*2^0
0000 0000 0000 0000 0000 0000 0000 0011
64 :1*2^6
0000 0000 0000 0000 0000 0000 0100 0000
-64:
1111 1111 1111 1111 1111 1111 1011 1111(64的反码)
1111 1111 1111 1111 1111 1111 1100 0000
**/
console.log(~25);//-26
console.log(25&3);//1
console.log(25|3);//27
console.log(25^3);//26
console.log(64>>5);//2
console.log(-64>>>5);//134217726
  1. 布尔操作符
/**
逻辑非(!)规则:
1.如果操作数是对象,则返回false。
2.如果操作数是空字符串,则返回true。
3.如果操作数是非空字符串。则返回false。
4.如果操作数是数值0,则返回true。
5.如果操作数是非0数值(包括Infinity),则返回false。
6.如果操作数是undefined,NaN或null,则返回true。
**/
console.log(!false);//true
console.log(!"blue");//false
console.log(!0);//true
console.log(!NaN);//true
console.log(!"");//true
console.log(!1234);//false
/**
逻辑与(&&)规则:
1.如果第一个操作数是对象,则返回第二个操作数。
2.如果第二个操作数是对象,则只有第一个操作数求值为true才会返回该对象。
3.如果两个操作数都是对象,则返回第二个操作数。
4.如果有一个操作数为null,则返回null。
5.如果有一个操作数为NaN,则返回NaN。
6.如果有一个操作数为undefined,则返回undefined。
短路:如果第一个操作数是false,那么永远不会对第二个操作数求值。
**/
let o1={foo:"foo"};
let o2={bar:"bar"};

console.log(o1&&3);//3
console.log(o1&&o2);//{bar: "bar"}
console.log(NaN&&o1);//NaN
/**逻辑或(||)规则:
1.如果第一个操作数是对象,则返回第一个操作数。
2.如果第二个操作数求值为false,则返回第二个操作数。
3.如果两个操作数都是对象,则返回第一个操作数。
4.如果两个操作数都是null,则返回null。
5.如果两个操作数都是NaN,则返回NaN。
6.如果两个操作数都是undefined,则返回undefined。
短路:如果第一个操作数是true,第二个操作数就不会再被求值了。
**/
let o1={foo:"foo"};
let o2={bar:"bar"};

console.log(o1||3);//{foo:"foo"}
console.log(false||o2);//{bar: "bar"}
console.log(true||o1);//true
  1. 乘性操作符
/**
乘法操作符:
1.如果操作数都是数值,则执行常规的乘法运算。
2.如果有任意操作数是NaN,则返回NaN。
3.如果是Infinity乘以0,则返回NaN。
4.如果是Infinity乘以非0的有限数值,则根据第二个操作数的符号返回Infinity或-Infinity。
5.如果是Infinity乘以Infinity,则返回Infinity。
6.如果有不是数值的操作数,则先在后台用Number()转换成数值,再应用上述规则。
**/
console.log(NaN*2);//NaN
console.log(Number.POSITIVE_INFINITY*8);//Infinity
console.log(Infinity*-8);//-Infinity
console.log(Infinity*0);//NaN
console.log(Infinity*Infinity);//Infinity
console.log("10"*3);//30
/**
除法操作符:
1.如果操作数都是数值,则执行常规的除法运算。
2.如果有任意操作数是NaN,则返回NaN。
3.如果是Infinity除以Infinity,则返回NaN。
4.如果是0除以0,则返回NaN。
5.如果是非0的有限制除以0,则根据第一个操作数的符号返回Infinity或-Infinity。
5.如果是Infinity除以任何数值,则根据第二个操作数的符号返回Infinity或-Infinity。
6.如果有不是数值的操作数,则先在后台用Number()转换成数值,再应用上述规则。
**/
console.log(NaN/2);//NaN
console.log(Number.POSITIVE_INFINITY/8);//Infinity
console.log(Infinity/-8);//-Infinity
console.log(0/0);//NaN
console.log(Infinity/Infinity);//NaN
console.log("30"/3);//10
console.log(-10/0);//-Infinity
/**
取模操作符:
1.如果操作数都是数值,则执行常规的除法运算,返回余数。
2.如果被除数是无限值,除数是有限值,则返回NaN。
3.如果被除数是有限值,除数是0,则返回NaN。
4.如果是Infinity除以Infinity,则返回NaN。
5.如果被除数是有限值,除数是无限值,则返回被除数。
6.如果被除数是0,除数不是0,则返回0。
7.如果有不是数值的操作数,则先在后台用Number()转换成数值,再应用上述规则。
**/
console.log(9%2);//1
console.log(100%Infinity);//100
console.log(Infinity%-8);//NaN
console.log(10%0);//NaN
console.log(Infinity%Infinity);//NaN
console.log(-10%Infinity);//-10
console.log(0%Infinity);//0
console.log("30"%3);//0
  1. 指数操作符
console.log(Math.pow(3,2));//9
console.log(3**2);//9
console.log(Math.pow(16,0.5));//4
console.log(16**0.5);//4
  1. 加性操作符
/**
加法操作符:
1.如果任一操作数是NaN,则返回NaN。
2.如果是Infinity加Infinity,则返回Infinity。
3.如果是-Infinity加-Infinity,则返回-Infinity。
4.如果是Infinity加-Infinity,则返回NaN。
5.如果+0加+0,则返回+0。
6.如果-0加+0,则返回+0。
7.如果-0加-0,则返回-0。
8.如果两个操作数都是字符串,则将第二个字符串拼接到第一个字符串后面。
9.如果只有一个操作数是字符串,则将另一个操作数转换为字符串,再将两个字符串拼接在一起。
**/
let o={
	toString(){
		return 33;
	}
}
console.log(NaN+1);//NaN
console.log(Infinity+Infinity);//Infinity
console.log(-Infinity + -Infinity);//-Infinity
console.log(Infinity + -Infinity);//NaN
console.log(0+0);//0
console.log(-0+0);//0
console.log(-0 + -0);//-0
console.log("22"+"55");//"2255"
console.log("22"+55);//"2255"
console.log("22"+null);//"22null"
console.log("22"+false);//"22false"
console.log("22"+o);//"2233"
/**
减法操作符:
1.如果任一操作数是NaN,则返回NaN。
2.如果是Infinity减Infinity,则返回NaN。
3.如果是-Infinity减-Infinity,则返回NaN。
4.如果是Infinity减-Infinity,则返回Infinity。
5.如果是-Infinity减Infinity,则返回-Infinity。
6.如果+0减+0,则返回+0。
7.如果-0减+0,则返回-0。
8.如果-0减-0,则返回+0。
9.如果有任一操作数是字符串,布尔值,null或undefined,则先在后台使用Number()将其转换为数值,再应用上述规则。
10.如果有任一操作数是对象,则调用其valueOf()方法取得表示它的数值。
**/
let o={
	valueOf(){
		return 33;
	}
}
console.log(NaN-1);//NaN
console.log(Infinity-Infinity);//NaN
console.log(-Infinity - -Infinity);//NaN
console.log(Infinity - -Infinity);//Infinity
console.log(-Infinity - +Infinity);//-Infinity
console.log(0-0);//+0
console.log(-0-0);//-0
console.log(-0 - -0);//+0
console.log("22"-"55");//-33
console.log("22"-55);//-33
console.log("22"-false);//22
console.log("22"-o);//-11
  1. 关系操作符
/**
>,<,<=,>= :
1.如果操作数都是数值,则执行数值比较。
2.如果操作数都是字符串,则逐个比较字符串中对应字符的编码。
3.如果任一操作数是数值,则将另一个操作数转换为数值,执行数值比较。
4.如果任一操作数是对象,则调用其valueOf()方法,取得结果后再根据前面的规则执行比较。
5.如果任一操作数是布尔值,则将其转换为数值再执行比较。
6.如果任一操作数是NaN,则返回false。
**/
console.log(3>2);//true
console.log("caB">"cAb");//true
console.log(0>true);//false
console.log("2">4);//false
console.log(NaN>4);//false
console.log(NaN<4);//false
  1. 相等操作符
/**
=,!= :
1.如果任一操作数是布尔值,false转换为0,true转换为1,再进行比较。
2.如果一个操作数是字符串,另一个操作数是数值,尝试将字符串转换为数值,再进行比较。
3.如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法取得其原始值,再根据前面规则比较。
4.null和undefined相等。
5.如果任一操作数是NaN,则相等操作符返回false,不相等操作符返回true。
6.如果两个操作数都是对象,则比较它们是不是同一个对象。
**/
let n;
console.log(null==n);//true
console.log("NaN"==NaN);//false
console.log(5==NaN);//false
console.log(NaN==NaN);//false
console.log(NaN!=NaN);//true
console.log(false==0);//true
console.log(true==1);//true
console.log(true==2);//false
console.log(true==2);//false
console.log(null==0);//false
console.log(n==0);//false
console.log("5"==5);//true
/**
===,!== :
与==,!==类似,不过它们比较时不转换操作数。
**/
console.log("5"===5);//false
  1. 条件操作符
console.log(5>3?5:3);//true
  1. 赋值操作符
let num=1;
console.log(num+=1);//2
console.log(num-=1);//1
console.log(num*=2);//2
console.log(num/=2);//1
console.log(num%=2);//1
console.log(num<<=1);//2
console.log(num>>=1);//1
console.log(num>>>=1);//0
  1. 逗号操作符
let num1=1,num2=2,num3=3;
let num=(1,2,3,4,5);
console.log(num);//5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值