深拷贝的三种方式
1,JSON.parse(JSON.stringjfy(obj))
缺点:取不到undefined的key,如果对象里有函数,函数无法被拷贝下来,无法拷贝对象原型链中的属性和方法
2,Object.assign({},obj)
缺点:不是真正的深拷贝,属性是对象的时候,对象还是浅拷贝
3,递归方式实现深拷贝
数据类型
基本数据类型:Undefined、Null、Boolean、Number、String
引用数据类型:Object
typeof
检测null时会返回object,
因为null类型的机器码全是0,
而typeof检测到后三位全是0的时候,会返回object
检测到object类型之后,会再次调用内部的一个[[call]]函数,如果有则返回function,否则返回object
let str = "asdf";
typeof返回string,栈类型存储
let str = new String("asdf")
typeof 返回object,堆类型存储
instanceof
通过原型链来检测,返回boolean值,true false
A instanceof B
A是否是B的实例对象
浮动数相加不准确问题在于计算机会把浮点数转成二进制 超过计算机存储长度之后 会舍掉 导致转换回来之后数字不精确
// 省略小数点2位之后数字
console.log(parseFloat(0.1+0.2).toFixed(2));
//转成整数类型
function add(m1,m2){
var m=Math.pow(10,2);
return (m1*m+m2*m)/m
}
console.log(add(0.1,0.2));
NaN undefined 0 null "" 会转换成false
其余都是true
基本数据(简单数据类型 值类型)类型存放在栈中,引用数据类型(复杂数据类型 对象类型)的数据存放在堆中,但是引用数据类型的地址存放在栈中
typeof检测引用类型function的时候 会返回function 而不是object,这是在设计js的时候检测引用类型,会检查是否包含[ [call] ]方法,包含的会返回function 不包含的返回object
typeof检查null的时候 返回的数据类型是根据机器码的后三位而决定的 当检测到null的时候返回000 =>object
function instanceof(A,B){ let p=A while(p){ if(p===B.prototype){ return true } p=p._proto_ } return false }
typeof 返回的是数据的类型,instanceof返回的是布尔值
遍历赋值 -> 简单循环赋值是浅拷贝,递归循环判断类型赋值:是深拷贝
Object.create() -> 简单循环赋值是浅拷贝,递归循环判断类型赋值:是深拷贝
JSON.parse()和JSON.stringify() ->深拷贝
深浅拷贝:假设B复制了A,当修改A时,看B是否发生变化,B变了,说明时浅拷贝;B没变,就是深拷贝
老师讲得好老师讲得好老师讲得好
老师讲得好老师讲得好
老师讲得好
几点回家的话
讲得好
vue html css js 算法和数据结构 设计模式。万变不离其宗。 js js js
Object.defineProperty()方法
传入三个参数
1.obj:需要定义属性的对象。
2.prop:需要定义的属性。
3.descriptor:属性的描述描述符
返回值:返回此对象。
var obj={};
var descroptor={
configurable:false//表示该属性能否通过delete删除,能否修改属性的特性或者能否修改访问器属性,默认为false.当且仅当该属性为true时,才能实现上述行为。
writeable:false//表示该属性的值是否可写,默认为false.当且仅当该属性为true时,才能实现上述行为。)
}
enumerable:false,表示该属性是否可以枚举,即是否通过for...in访问属性 默认是false.
value:hello world.表示该属性的值,默认是undefinde
js继承的6种方式:
简单原型链:类式继承
借用构造函数:缺点=>父类的原型方法自然不会被子类继承
组合继承(最常用):类式继承+构造函数式继承
寄生组合继承(最佳方式):寄生式继承+构造函数式继承
原型式:跟类式继承一样。父类对象book种的值类型的属性被复制,引用类型的属性被共有。
寄生式:通过在一个函数内的过度对象实现继承并返回新对象的方式。
Function 对象和object对象之间的关系Person AA
Function是顶层的构造器,Object是顶层的对象{}
顶层现有null,Object.prototype,Function.prototype Function
从原型上说:Function继承了Object
构造器上说:Function构造了Object new Object
function object(){}
构造函数构建类
function Person(name,age){
this.name=name
this.age=age
this.say=function(){
console.log('我是'+this.name)
}
}
var p1=new Person('张三',18)
var p2=new Person('李四',20)
构造函数object
原型和原型链
1万物皆对象,万物皆空 (对象最终指向null)
2原型:保存所有子对象的共有属性值和方法的父对象。
原型链:是各级子对象的_proto_属性连续引用形成的结构。
3.三个属性:_proto_,constructor,prototype
_proto_下划线开始下划线结束都是js内部属性
什么是对象:
1具备私有属性{a:1}
只要是new出来的都是对象,new fun()=>实例化
不同对象肯定不相等 var a=[1]; var b=[1]; a==b =.false
对象都会有引用机制 堆 栈
js中万物皆对象 Array Date Object Function String
面向对象:
把任何的数据和行为抽象成一个形象的对象,类似于人生活中思考的方式,
类:对象(object)的模板,定义了同一组对象(又称“实例”)共有的属性和方法
面向对象oop:继承 封装 多态
继承:子继承父
封装:方法 function(){} 把方法写在function里面
多态:重载,重写。 继承 父类 覆盖掉父类方法
this的坑
this的指向
指代当前调用的对象,四种绑定规则分别是:默认绑定,隐式绑定,显示绑定,new绑定,优先级从低到高。
new统称为实例化。
4步:
1新创建一个对象obj
2把obj的proto指向构造函数的prototype对象,实现继承。
3将步骤1新创建的对象obj作为this的上下文
4返回创建的对象obj(如果该函数没有返回对象,则返回this)
Function对象call,apply,bind
1,apply()方法调用一个函数,其中有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数。
Function.apply(obj,args)方法能接收两个参数。
**call和apply的区别
call是单个的参数传入,apply是以数组的形式传入。
var arr=Array.prototype.slice.apply(arguements)//arguements就是一个类数组
bind :类似与call 但是与其不同的是,call调用之后可以立即执行,但是bind需要用一个变量进行接受之后再执行
比如
var val= stu1.say.bind 这样
闭包本质就是作用域
1,是引用了自由变量得函数这个被引用得自由变量将和这个函数一同存在,及时离开了创造他得环境也不例外。所以 有另一种说法认为闭包是自由函数和其相关的引用环境组合而成。
闭包的缺点:会导致内存的驻留。
let也可以实现信息驻留
开发中重载
在程序中可以定义相同名字,不同参数的形式的不同函数,函数在调用的函数的时候,自动识别不同参数对应的函数,实现了相同函数名不同的函数调用
function React(){//arguments[x,y,z]参数值,类数组 x xy xyz
//如果传入的是一个参数,那就返回一个正方形
if(arguments.length>=1){
this.width=arguments[0];
this.height=arguments[0];
}
//如果传入的是两个参数,那就返回一个长方形
if(arguments.length>1){
this.width=arguments[0];
this.height=arguments[1];
}
this.toString=function(){
return 'width:'+this.width+'height:'+this.height;
}
}
var r1=new React(10);
console.log(r1.toString());
var r2=new React(10,9);
console.log(r2.toString());
多态:同一个东西表现得不同状态,重写和重载
js执行环境
单线程执行
执行环境(执行上下文)
全局执行环境
局部执行环境
变量对象:vo variable object 一般是全局环境下保存变量的对象{a:1,b:2....}
活动对象:AO Activation object 函数的执行环境是在调用时创建的,该对象将代替vo对象来保存当前函数环境中的变量,参数,函数,所以在函数执行环境中vo就是AO function(){a==1,b==1}
js es5中
作用域scope 一个变量的可用范围;{a:1}{b:2}这些都是作用域。两个互不相干,一个封闭式环境内保证我这个变量能用,两个不相关联的作用域,再没有任何外部关联的情况下不能相互作用。
作用域链 scope chain:以当前作用域的scope属性为起点依次引用每个AO(active object),直到window结束,形成多级引用关系。【{a:1}--{b:2}--{}--{}--{}--...window】作用域链
js作用域:ES5
分为两大类:全局作用域(js-window,var a=1就是一个全局作用域,所有的函数里面要用也是能找到的。),函数作用域( function(){},每定义一个function 大括号里面就是一个作用域。 )。