前言:零零碎碎整理,有错误欢迎路过的朋友仔指出
1.&& 优先级高于 ||
console.log(3 || 2 && 1) //3
先算2&&1,返回2,再算3||2,返回3
2.读取对象值对象名.属性 === 对象名[‘属性’]
let obj = { name : 'xiaolin' }
console.log(obj.name === obj['name']) //true
一般使用.即可,在遇到属性为变量时,必须用[]
4.基本数据类型:string number boolen null undefined Symbol,引用数据类型:object
5.基本数据类型存储在栈内存中,变量值保存值;对象存储在堆内存中,变量值保存地址,在赋值时两个变量指向同一个内存地址(引用) 6.深浅拷贝(深浅复制) 一句话总结,基本数据类型没有深浅拷贝之分,默认为深拷贝,拷贝的都是具体的值的副本;对于引用数据类型来说,浅拷贝拷贝的是对象引用的地址,深拷贝拷贝的是具体的值的副本
//基本数据类型,在复制后修改使用彼此间不会互相影响
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){ //判断是否是null对象
res = null
} else if (target instanceof RegExp){ //判断是否是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'}
7.var变量声明提升,把声明提到最前面再依次执行;函数声明提前,可以在创建前调用
var a = 2; console.log(a) //undefined
//等同于var a; console.log(a), a = 2 //undefined
foo(); //具名函数先调用后定义可以正常使用,存在函数提升,输出foo
function foo() {
console.log('foo');
}
8.变量的查找,函数在本级找变量,找得到用本级,找不到往上一级找,即作用域链
function wrap() {
var a = 1
return function () {
console.log(a) //变量a在本作用域找不到值,往上一层找,以此往上直到全局
}
}
wrap()() //1
10.构造函数,先定义一个构造函数,再new一个实例
function People(name) {
this.name = name;
this.getName = function(){
console.log(this.name);
}
}
var p1 = new People('xiaolin') //new一个实例
p1.getName(); //调用,输出xiaolin
11.每个构造函数都有一个属性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
12.在打印对象时输出[object,object]是因为输出时调用了toString()方法,如果希望在输出对象时不输出[object Object],可以为对象的原型上修改toString()方法
对象.prototype.toString = function(){
return "[属性="+this.属性+",属性="+this.属性"]"
}
13.数组方法
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 //从大到小排序
}));
14.数组遍历
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
})
15.数组去重,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);
16.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
17.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
18.字符串方法
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,'']
19.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是第一个参数,第16点已说明
20.window.onload在文档加载完成之后就会触发该事件,可以为此事件注册事件处理函数,并将要执行的脚本代码放在事件处理函数中,就可以避免获取不到对象的情况。当js代码需要获取页面中的元素时,如果script标签在元素的前面,需要加window.onload;如果script放在了元素后面,就不需要加 window.onload。
22.事件委托,将事件统一绑定给祖先元素,原理是利用了事件冒泡
待补充
23.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]
24.判断数据类型
//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
待补充…
|