js高级知识
js数据类型:
1、基本(值)类型:
String:任意字符串
Number:任意数值
boolean: True False
undefined: undefined
null: null
undefined 和null 区别: undefined 定义了变量未赋值 null定义了变量并赋值为null
var a; typeof a 是'undefined'
a=null typeof a 是 ‘object'
什么时候用null:
var c=null 初始赋值为null,表明将要赋值为对象
c=[1,4,334]
c=null 最后将赋值为null 等待垃圾回收器进行回收释放内存
2、 对象(引用)类型 :
Object: 任意对象
Function: 一种特殊对象(可以执行)
Array: 一种特殊对象(数值下标,有序的)
数据类型判断:
typeof: 返回的结果是变量的数据类型字符串('undefined' 'string' 'number' 'object' 'boolean' 'function')
instanceof: 用于对象类型 判断对象具体类型
===: undefined null
var a ;
console.log(a, typeof a, a === undefined, typeof a === 'undefined') // undefined 'undefined' true true
a=4
console.log( typeof a === 'number') //true
a='www'
console.log( typeof a === 'string') //true
a=null
console.log( typeof a, a===null) //'object' true
var b1= {
b2: [1,'abc',console.log],
b3: function() {
console.log('b3')
}
}
console.log(b1 instanceof Object, b1 instanceof Array) // true false
console.log(b1.b2 instanceof Object, b1.b2 instanceof Array) // true false
console.log(b1.b3 instanceof Object, b1.b3 instanceof Function) // true true
3、变量内存
var a=xxx //若xxx是基本类型 则a内存存储的是xxx值 若xxx是对象类型 则a内存存储的是对xxx堆内存地址
var obj1= {name:'tom'}
var obj2=obj1 //此时obj1 obj2同时指向堆内存同一个对象内存地址
obj1.name ='jack'
console.log(obj2.name) // jack
obj2.age=22
console.log(obj1.age) //22
function fun1(obj) {
obj.name='AAA'
}
fun1(obj1)
console.log(obj2.name) // AAA
在js调用函数时传递变量参数时,是值传递(基本类型是值 引用类型是对象内存地址值)
var a=3
function fun(a){
a=a+1
}
fun(a)//此时传的是变量a的值3
console.log(a) //3
var obj={name:'howhy'}
function fun1(obj){
console.log(obj.name) //howhy
}
fun1(obj) //此时传递的是obj的内存地址值
局部变量函数执行完时释放 对象最后由垃圾回收器进行回收
4、函数
函数定义有两种方法:1、 函数声明 function fun() {} 2、函数表达式 var fun1=function(){}
函数执行:1、括号 2、Object.fun1() 3、函数名.call/apply(对象) 这样执行可以改变方法的this(也就是可以将这个方法添加到任意对象)
var obj={}
function test(){
this.xxx='xxx111'
}
test.call(obj)
console.log(obj.xxx) //xxx111
回调函数的特点:1、自定义的 2、 没有手动调用 3、它自己执行了 例如:dom事件 setTimeout
IIFE: Immediately-Invoked Function express 立即执行函数表达式 //隐藏实现 不会污染全局命名空间 编译js代码
(function(){
var a=1
function test(){
console.log(++a)
}
window.$=function(){
return {test: test}
}
})()
$().test() // 2
5、this : 1、任何函数的本质执行都是通过某个对象调用执行的,如果没有直接指定就是window 2、所有函数内部都有一个变量this 3、它的值就是调用函数的当前对象
6、js语句是否加分号编码问题:js一条语句后可不加分号 下面两种情况需在语句前加分号:小括号或中括号开头的语句
var a=3 ;(function(){ console.log(11111111) })() var b=4 ;[1,3,4].forEach(function(){})
7、原型链 1、每个函数(类)都有一个prototype属性,即显式原型(属性) 2、每个实例对象都有一个__proto__即隐式原型(属性)
3、对象实例的隐式原型的值为对象显式原型的值 new Date().__proto__===Date.prototype
对象属性查找:1先查找自身隐性原型 然后查找对象显式原型
4、函数的显式原型指向的对象默认是空Object的实例对象
console.log(fn.prototype instanceof Object) //true
console.log(Object.prototype instanceof Object) //false
console.log(Function.prototype instanceof Object) //true
5、所有函数都是Function的实例 console.log(Function.__proto__===Function.prototype)
6、 Object的原型对象是原型链的尽头 console.log(Object.__proto__.prototype) //null
8、变量定义时 1、加var变量会提升 不加var不会提升 2、不加var定义时变量也是全局变量 3、加var定义的变量既可以是全局变量也可以是局部变量
9、 this 1、函数独立调用(没有点前面对象或用call apply) this 就是window 2、对象调用点 this就是对象 3、显式调用 call apply bind this 是参数对象
10、new的过程 1 、创建一个空对象 2、 将this指向该空对象 3、将空对象的隐性原型指向构造函数的显式原型 4、返回该对象
function clsNew(fn,args){ let obj={} fn.apply(obj,args) obj.__proto__=fn.prototype return obj } function Person(name){ this.name=name } Person.prototype.say=function(){ console.log(this.name) } let p=clsNew(Person,['howhy']) p.say()
//原型链继承:核心:Student.prototype=new Person() 缺点:若父类有引用数据类型属性,若一个子类对象改了这个属性值,另一个子类对象也随着改变了 // function Person(name){ // this.name=name // this.score=[88,84] // } // Person.prototype.say=function(){ // console.log(this.name) // } // function Student(name){ // this.name=name // } // Student.prototype=new Person() // Student.prototype.constructor=Student // let s1=new Student('www') // s1.say() // s1.score[0]=80 // console.log(s1.score)//[80,84] // console.log(new Person().score) // let s2=new Student('www111') // s2.say() // console.log(s2.score)//[80,84] //组合继承 核心:Student.prototype=new Person() Person.call(this,name) 缺点:每生成一个子类对象 父类都被调用一次 function Person(name){ this.name=name console.log('new Person') } Person.prototype.say=function(){ console.log(this.name) } function Student(name,age){ Person.call(this,name) this.age=age } Student.prototype=new Person() Student.prototype.constructor=Student let s3=new Student('www2',22) s3.say() //Object.create Object.create(null) //创建一个没有原型的对象 let obj={ 'name':'create' } let nobj=Object.create(obj) //创建一个原型对象为obj的对象 console.log(nobj) //class extends class Animal{ constructor(name){ this.name=name } call(){ console.log(this.name+' call') } } let an=new Animal('dog') an.call() class Pig extends Animal{ constructor(name,className){ super(name) this.className=className } } let pg=new Pig('pig') pg.call()
//cache class class WebCache{ constructor(isLocal=true){ this.storage=isLocal?localStorage:sessionStorage } setItem(key,value){ if(value){ this.storage.setItem(key,JSON.stringify(value)) } } getItem(key){ let value=this.storage.getItem(key) if(value){ value=JSON.parse(value) return value } } removeItem(key){ this.storage.removeItem(key) } clear(){ this.storage.clear() } } //cache function function webCache(islocal){ this.storage=isLocal?localStorage:sessionStorage } webCache.prototype.setItem=function(key,value){ if(value){ this.storage.setItem(key,JSON.stringify(value)) } } webCache.prototype.getItem=function(key){ let value=this.storage.getItem(key) if(value){ value=JSON.parse(value) return value } } webCache.prototype.removeItem=function(key){ this.storage.removeItem(key) } webCache.prototype.clear=function(){ this.storage.clear() }
###检测数据类型方法
let checkType=data=> Object.prototype.toString.call(data).slice(8,-1).toLowerCase() console.log(checkType(1111))