携手创作,共同成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
-
&& 优先级高于 ||
console.log(3 || 2 && 1) //3 先算2&&1,返回2,再算3||2,返回3 -
读取对象值 对象名.属性===对象名[‘属性’],一般使用.即可,在遇到属性为变量时,必须用[]
let obj = { name : 'xiaolin' } console.log(obj.name === obj['name']) //true -
基本数据类型:string number boolen null undefined Symbol,引用数据类型:object
-
基本数据类型存储在栈内存中,变量值保存值;对象存储在堆内存中,变量值保存地址,在赋值时两个变量指向同一个内存地址(引用)
-
深浅拷贝(深浅复制),一句话总结,基本数据类型没有深浅拷贝之分,默认为深拷贝,拷贝的都是具体的值的副本;对于引用数据类型来说,浅拷贝拷贝的是对象引用的地址,深拷贝拷贝的是具体的值的副本
//基本数据类型,在复制后修改使用彼此间不会互相影响 let str = 'xiaolin' let str2 = str console.log(str) //xiaolin console.log(str2) //xiaolin str = 'xiaolin6' console.log(str) //xiaolin6 console.log(str2) //xiaolin //引用数据类型-浅拷贝,拷贝了堆内存中的地址,在复制后修改使用彼此间会互相影响 let obj = { name:'xiaolin', age:24 } let obj2 = obj console.log(obj) //{name:'xiaolin',age:24} console.log(obj2) //{name:'xiaolin',age:24} obj.name = 'xiaolin6' console.log(obj) //{name:'xiaolin6',age:24} console.log(obj2) //{name:'xiaolin6',age:24} //引用类型-深拷贝 //1.Object.assign let obj = { name:'xiaolin', age:24 } let obj2 = Object.assign({},obj) console.log(obj); //{name:'xiaolin',age:24} console.log(obj2); //{name:'xiaolin',age:24} obj.name = 'xiaolin6' console.log(obj) //{name:'xiaolin6',age:24} console.log(obj2) //{name:'xiaolin',age:24} //2.递归 var obj = { name:'xiaolin' } function deepCope(target) { let res if(typeof(target) === 'object'){ if(Array.isArray(target)){ res = [] for(let i in target){ res.push(deepCope(target[i])) } } else if (target === null){ res = null } else if (target instanceof RegExp){ res = RegExp } else { res = {} for(let i in target){ res[i] = deepCope(target[i]) } } } else { res = target } return res } var obj2 = deepCope(obj) console.log(obj2) //{name:'xiaolin'} obj2.name = 'xiaolin6' console.log(obj) //{name:'xiaolin'} console.log(obj2) //{name:'xiaolin6'} -
var变量声明提升,把声明提到最前面再依次执行;函数声明提前,可以在创建前调用
var a = 2; console.log(a) //undefined //等同于var a; console.log(a), a = 2 //undefined foo(); //具名函数先调用后定义可以正常使用,存在函数提升,输出foo function foo() { console.log('foo'); } -
变量的查找,函数在本级找变量,找得到用本级,找不到往上一级找,即作用域链
function wrap() { var a = 1 return function () { console.log(a) //变量a在本作用域找不到值,往上一层找,以此往上直到全局 } } wrap()() //1 -
构造函数,先定义一个构造函数,再new一个实例
function People(name) { this.name = name; this.getName = function(){ console.log(this.name); } } var p1 = new People('xiaolin') //new一个实例 p1.getName(); //调用,输出xiaolin -
每个构造函数都有一个属性prototype,对应一个原型对象 == 在构造函数上new的实例都有一个__proto__属性,对应一个原型对象实例找属性时首先向构造函数找再向原型找,原型对象就像是一个公共区域,可以把共有的属性和方法添加到原型对象,避免污染全局,可以通过hasOwnProperty方法检查自身有没有该属性
function People(name,age) { this.name = name; this.age = age; this.getName = function(){ console.log(this.name); } } var p1 = new People('xiaolin',24) p1.getAge() //报错,方法未定义 People.prototype.getAge = function () { //在原型上添加 console.log(this.age); } var p2 = new People('xiaolin',24) p2.getAge() //24 console.log( p2.hasOwnProperty('getAge')); //false,方法存在原型上,不在构造函数上 console.log(People.prototype === p2.__proto__); //true -
在打印对象时输出[object,object]是因为输出时调用了toString()方法,如果希望在输出对象时不输出[object Object],可以为对象的原型上修改toString()方法
var arr = [11,22,33] //for循环 for(let i =0;i<arr.length;i++){ console.log(arr[i]); //11,22,33 } //forEach arr.forEach((val)=>{ console.log(val); //11,22,33 }) -
数组方法
var arr = [11,22,33] var res = arr.push(44) console.log(res,arr) //4,[11,22,33,44],最后面新增,返回新的长度 var arr = [11,22,33] var res = arr.pop() console.log(res,arr); //33,[11,22],删除最后一个,返回删除元素 var arr = [11,22,33] var res = arr.unshift(44) console.log(res,arr); //4,[44,11,22,33],在前面新增,返回新的长度 var arr = [11,22,33] var res = arr.shift() console.log(res,arr); //11,[22,33] ,删除最前面一个,返回删除元素 var arr = [11,22,33] console.log(arr.slice(1,3)); //[22,33] ,截取,前开后闭 var arr = [11,22,33] arr.splice(1,1) console.log(arr); //[11,33],删除,(index,num) var arr = [11,22,33] arr.splice(1,1,44) console.log(arr); //[11,44,33],替换,(index,1,newchange) var arr = [11,22,33] arr.splice(1,0,44) console.log(arr); //[11,44,22,33],增加,(index,0,newadd) var arr = [11,22,33] var arr2 = [44,55] console.log(arr.concat(arr2)); //[11,22,33,44,55],数组连接 var arr = [11,22,33] console.log(arr.join()); //11,22,33,数组转字符串 var arr = [11,22,33] console.log(arr.reverse()); //[33,22,11],数组反转 var arr = [11,22,33] console.log(arr.sort((a,b)=>{ return a-b; //从小到大排序 return b-a //从大到小排序 })); -
数组遍历
var arr = [11,22,33] //for循环 for(let i =0;i<arr.length;i++){ console.log(arr[i]); //11,22,33 } //forEach arr.forEach((val)=>{ console.log(val); //11,22,33 }) -
数组去重,for双循环
var arr = [33,11,22,33,44,22,22,11,55,55,66] for(let i = 0;i < arr.length; i++){ for(let j = i+1;j < arr.length;j ++){ if(arr[i] === arr[j]){ arr.splice(j,1); j--; } } } console.log(arr); -
call和apply,都是函数对象的方法,需要函数对象调用,传的第一个参数可以改变执行上下文的this,call第二个参数是依次传,apply第二个参数是数组
var sing = { singing:function(name,skill){ this.skill = skill this.name = name console.log(`my name is ${this.name},can ${this.skill} and ${this.skill2}`,); } } var dance = { skill2:'sleep' } sing.singing.call(dance,'xiaolin','dance') //my name is xiaolin,can dance and sleep sing.singing.apply(dance,['xiaolin','dance2']) //my name is xiaolin,can dance2 and sleep -
argument是类数组,保存传递的实参
function add() { console.log(Array.isArray(arguments)); //false,arguments是类数组 let sum = 0 for(let i=0;i<arguments.length;i++){ sum += arguments[i] } return sum } var getSum = add(1,2,3,4,5,6,7,8,9) console.log(getSum); //45 -
字符串方法
console.log('xiaolina'.charAt(5)) //i,索引所在字符 console.log('xiao'.concat('lina')) //xiaolina,拼接字符串 console.log('xiaolina'.indexOf('a')) //2,从前往后检索字符串,有则返回第一个index, console.log(('xiaolina'.indexOf('h'))) //-1,无返回-1 console.log('xiaolin'.lastIndexOf('a')) //7,同indexOf,顺序从后往前 console.log('xiaolin'.lastIndexOf('h')); //-1,无返回-1 console.log('xiaolin'.slice(1,3)); //ia,截取字符串,左闭右开 console.log('xiaolina'.substr(2,3)); //aol,截取字符串,(index,num) console.log('xiaoxiaoxiao'.split('o')); //[xia,xia,xia,''] -
this指向
//1.函数调用 function foo() { window.x = 1 console.log(this.x); } foo() //通过函数调用,this永远是window //2.方法调用 var obj = { name:'xiaolin', foo(){ console.log(this.name); } } obj.foo() //'xiaolin',通过方法调用,this指向调用方法的对象 //3.构造函数调用 function People() { return this } var p1 = new People() console.log(p1) //People,通过new创建实例,this指向新的实例对象 var p2 = People() console.log(p2) //Window,函数调用this指向window 4.以apply和call调用,this是第一个参数 -
window.onload在文档加载完成之后就会触发该事件,可以为此事件注册事件处理函数,并将要执行的脚本代码放在事件处理函数中,就可以避免获取不到对象的情况。当js代码需要获取页面中的元素时,如果script标签在元素的前面,需要加window.onload;如果script放在了元素后面,就不需要加 window.onload
-
js、json互转
//js对象转json对象 var obj = { name:'xiaolin',age:24 } console.log(JSON.stringify(obj)); //'{"name":"xiaolin","age":24}' //json对象转js对象 var jsonObj = '{ "name":"xiaolin","age":"24" }' console.log(JSON.parse(jsonObj)); //{name: 'xiaolin', age: '24'} //js数组转json数组 var arr = [1,2,3,4,5,6] console.log(JSON.stringify(arr)); //'[1,2,3,4,5,6]' //json数组转js数组 var jsonArr = '[1,2,3,4,5,6]' console.log(JSON.parse(jsonArr)); //[1,2,3,4,5,6] -
判断数据类型
//1. typeof可判断undefined number string boolen function console.log(typeof(undefined)) //undefined console.log(typeof(24)) //number console.log(typeof('xiaolin')) //string console.log(typeof(true )) //boolean console.log(typeof(Function)) //function //2.a instanceof b(判断a是不是b的实例,判断对象的具体类型) function People() { return } function Color() { return } var p1 = new People() var c2 = new Color() console.log(p1 instanceof People); //true console.log(c2 instanceof Color); //true console.log(c2 instanceof People); //false console.log([1,2,3] instanceof Array); //true //3.===,全等符可判断undefined null let a = null console.log(a === null); //true let a = undefined let b console.log(a === undefined); //true console.log(b === undefined); //true //4.其它 console.log(Array.isArray([1,2,3])); //true