创建对象的几种方式,创建对象是基于对象原型进行创建
//字面量创建对象 //对象是采用key:value键值对方式进行存储值,可以通过key来获取到他的值,多个属性采用逗号分开 //如果有下划线和中划线之类的可以让字符串当key,访问带有特殊字符的必须以花括号进行访问 //如果key和value里面的值都一样可以写成一个,函数也一样 let obj={ a:2,b:32,'a-vb':5}; let obj1=new Object(); obj1.name='112' //对象的值可以是任意数据类型,值为函数的话叫做方法 //访问对象的几种方法 obj.name obj.['name'] //区别:点的方式必须是对象里面有的,中括号的方式也必须是个字符串,也可以是变量和数字,但是点方法不能 //如果访问对象里面没有的属性则返回undefined
遍历对象
//遍历所有key的属性 let obj={ name:12,age:232 } Object.keys(obj) for(a in obj){ a是对象所有的key,这里只能使用obj【a】获取对象中的值 }
删除对象的属性
delete关建字 delete obj.name
构造函数
先通过new创建一个实例,实例就是根据构造函数创建出来的对象,可以先定义好对象有哪些默认的属性, 构造函数首字母大写 //创建构造函数 function Eag(name,age){ //创建出来的对象,当前的this指向创建出来的对象 this.name:name, this.age:age } //创建实例 let a= new Eag('wa',1231); //打印a,会打印出来 Eag这个构造函数
this
this指向本身,除箭头函数外,箭头函数指向的是包裹他作用域的this,对象没有作用域包裹箭头函数所以 this箭头函数不指向对像
对象原型
每一个对象都有一个prototype原型,如果函数是一个构造函数,那么他new出来的实例会继承他的对象原型, 每一个实例上面的__proto__都有一个constructor属性,这个属性就是他的构造函数,__proto__是他上一级的prototype function Eag(name,age){ this.name:name, this.age:age, this.sig(){ console.log(this.name+this.age) } } var emg1=new Eag('wa',121); var emg2=new Eag('121',121); 每一个创建的实例上面都有一个name和age属性,以及sig方法 //在往Eag的prototype上面添加一个属性,让emg1和emg2都能继承这个属性 构造函数都有一个prototype的属性,也是构造函数独有的 可以打印下看看 console.log(Eag.prototype); 往Eag原型上挂载数据,让emg1和emg2都能访问到 Eag.prototype.num='22'; Eag.prototype.nihao=function(){ console.log(this.name+'nihao') } console.log(emg1.num) emg1.nihao() 现在打印emg1.num就能打印出来22,emg2也是,因为原型链的缘故 在给构造函数prototype上面添加属性或者方法的时候,他创建实例都会继承下来 //访问对象的prototype 可以使用__proto__进行访问 console.log(emg1.__proto__); 也可以通过对象里面的方法进行获取 Object.getPrototypeOf(emg1)
对象继承
Object.create()可以让一个对象继承于另一个对象 新的对象可以拥有继承对象的所有属性,并还可以拥有自己特有的属性 var mag=Object.create(emg1); 可以采用Object.keys方法和for in 循环查看是否继承下来 查看对象全部的属性 Object.getOwnPropertyNames(mag)
原型链
原型链是每个对象的原型都还会有个上层的原型,直到遇到null,这种链式原型构成的原型链, js中最顶层的对象是object,object的原型是object.prototype,object.prototype的上层原型是null, 这样就达到了原型的顶端 //原型链 function Eag(age){ this.age:age, sing(){ console.log(11) } } let emg1=new Eag(12); //如果当前实例里面找不到方法就去原型上找原型上找不到方法就去构造函数上面找,构造函数上面找不到就去object原型上面找, 如果在找不到就返回null emg1.prototype=>Eag.prototype=>Object.prototype; //查看对象所属原型 Object.getPrototypeOf(value)
修改原型指向
//把第二个值的prototype指向给a,该了原型指向之后,a的原型指向会发生改变 Object.setPrototype(a,b.prototype)
spread 操作符 三个点…
... 三个点进行复制对象是深拷贝
值传递与引用传递
在js中数组和对象在函数的参数中是按引用去传递的,传递的是内存地址,修改他的值之后,所用使用该地址 的值都会发生变化,不过数字和布尔等基础类型是按照值传递的,就是基本数据类型的值会被复制一份 新的,在函数内部修改他的值之后不会影响他之前的值
call和apply以及bind方法
call的使用 let obj1={ name:'王朋真' } //函数 Callfn(a,b){ console.log('我的名字',this.name,a,b) } //当前的Callfn的this指向是window,可以通过call方法进行改变他的this指向,可以再函数调用前 //调用call方法进行改变this指向,然后在执行 //使用方法 函数.call(this指向的函数或者对象,当前函数需要传递的参数) Callfn.call(obj1,'我是小菜菜') apply的使用 //apply跟call的区别就是传递参数call是单个传递也是正常函数传参,但是apply是以数组方式进行传参 Callfn.apply(obj1,['我是小菜','大菜']) bind的使用 //bind的操作跟call是一样的,只不过bind是返回一个改变this之后的新函数,用于在后面调用他不会立即执行, 需要使用一个变量进行接收在进行执行 let fn1=Callfn.bind(obj1,'halo','发')
js的面向对象编程 从es6才开始有的
es6的面向对象也是prototype的语法糖,最后都会转化为原型进行执行 定义Class类,也相当于es5中的构造函数 //创建class类 Class Eag { //constructor方法 1.constructor方法是类的默认方法,通过new命令生成实例对象时,自动调用该方法. 2.一个类必须有constructor方法,如果没有显式定义,会默认添加一个空constructor方法 3.constructor默认返回实例对象(this),完全可以指定返回另外一个对象 constructor(name,age){ this.name=name; this.age=age; } //定义自定义方法 sigIt(){ console.log('定义方法') } } 继承 esg继承Eag Eag里面的所有方法esg都可以使用,esg是子类 eag是父类,一个子类只能继承一个父类 class Esg extends Eag{}