从今天起我们开始讨论javascript的面向对象面向对象概念理解面向对象语言有个标志=>它们都具有类的概念,通过类可以创建任意多个具有相同属性和方法的对象。面向对象有三大特性封装继承多态但JS中对象与纯面向对象语言中的对象是不同的JS中的对象:无序属性的集合,其属性可以包含基本值、对象或者函数。可以简单理解为JS的对象是一组无序的值,其中的属性或方法都有一个名字,根据这个名字可以访问相映射的值(值可以是基本值/对象/方法)。创建对象的基本方法我们前面在讲原型链的时候说过,两种创建对象的方法对象字面量(对象直接量)这是最快的一个????: const hero = { name:“欧阳锋”, nickname:“西毒”, doSth:function(){ console.log(‘灵蛇杖法’); }⚠️创建对象的属性名并不强制使用引号包裹,除了以下几种情况属性名中包含空格属性名中包含连字符(中划线)属性名中包含保留字const obj={ “go home”:“包含了空格”, “go-home”:“包含了连字符”, “for”:“这是保留字”}new 实例化一个对象通过new运算符创建并实例化一个新对象,new后面是一个构造函数const hero = new Object()hero.name = “欧阳锋"hero.nickname = “西毒"hero.doSth = function () { console.log(‘灵蛇杖法’);}两种创建方法是一样的创建对象通过以上两种方式似乎足够了,但是当场景稍微复杂一点,问题就显现出来了当我门创建很多结构相同的对象时,会产生大量的重复代码,为了解决这个问题,出现了一个解决方案工厂模式工厂模式抽象了创建具体对象的过程,因为javascript无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象一个????:function createHero(name,nickname,doSth) { const obj = new Object() obj.name=name obj.nickname=nickname obj.doSth = function () { console.log(doSth); } return obj}const hero1 = createHero(“欧阳锋”,“西毒”,“灵蛇杖法”)const hero2 = createHero(“黄药师”,“东邪”,“碧海潮生曲”)console.log(hero1)看下输出:hero1和hero2都直接继承自Object实例,工厂模式就是像工厂一样来创建对象,创建的每一个对象都是通过new Object()来创建的后来,开发人员有发现了更好的模式构造函数模式我们之前讨论过,通过使用自定义构造函数来实例化对象function Hero(name, nickname, doSth) { this.name = name this.nickname = nickname this.doSth = function () { console.log(doSth); }}const hero3 = new Hero(“欧阳锋”,“西毒”,“灵蛇杖法”)const hero4 = new Hero(“黄药师”,“东邪”,“碧海潮生曲”)console.log(hero3);注意⚠️:创建自定义构造函数,函数名首字母大写,用来和非构造函数进行区分我们继续看下输出:hero3是通过Hero实例化出来的,所以hero3先继承自Hero要创建Hero的新实例,必须使用new操作符,以这种方式调用构造函数实际上会经历以下四个步骤,创建一个新对象将构造函数的作用域赋给新对象(因此this就指向了这个新对象)执行构造函数中的代码(为这个新对象添加属性)返回新对象hero3和hero4都是Hero的实例,同时也是Object的实例instanceof用于判断一个变量是否某个对象的实例console.log(hero3 instanceof Hero);//=>trueconsole.log(hero3 instanceof Object);//=>trueconsole.log(hero4 instanceof Hero);//=>trueconsole.log(hero4 instanceof Object);//=>true属性和方法(公有&私有)????的????中,我们将属性和方法绑定在了构造函数Hero中的this上,hero3和hero4都可以访问这些属性绑定在this上的属性我们称之为公有属性绑定在this上的方法我们称之为公有方法也就是说通过构造函数Hero实例化出来的对象是可以方位公有属性和公有方法的既然有公有属性和公有方法,就一定会有私有属性和私有方法我们做一下调整function Hero(name, nickname, doSth) { let test = “私有属性” function method(){console.log(“私有方法”);} this.name = name this.nickname = nickname this.doSth = function () { console.log(doSth); }}const hero3 = new Hero(“欧阳锋”,“西毒”,“灵蛇杖法”)const hero4 = new Hero(“黄药师”,“东邪”,“碧海潮生曲”)console.log(hero3);看下输出:在hero3中是不存在构造函数的私有属性和私有方法的如果我们这创建完构造函数后,追加一下属性和方法,会怎么样呢?试试看 function Hero(name, nickname, doSth) { let test = “私有属性” function method(){console.log(“私有方法”);} this.name = name this.nickname = nickname this.doSth = function () { console.log(doSth); } } Hero.localAttr=“测试属性” Hero.localMethod=function(){ console.log(‘测试方法’); } Hero.prototype.proAttr=“原型属性” Hero.prototype.proMethod=function(){ console.log(‘原型方法’); } const hero3 = new Hero(“欧阳锋”,“西毒”,“灵蛇杖法”) const hero4 = new Hero(“黄药师”,“东邪”,“碧海潮生曲”) console.log(hero3); console.log(’localAttr测试属性:’,hero3.localAttr); console.log(“localMethod测试方法:",hero3.localMethod); console.log(“proAttr原型属性:",hero3.proAttr); console.log(“proMethod原型方法:",hero3.proMethod);看输出:创建完实例对象后,通过.运算符添加的属性是类静态公有属性(实例化的对象无法访问)通过.运算符添加的方法是类静态公有方法(实例化的对象无法访问)通过原型链添加的属性是公有属性(实例化的对象可以访问)通过原型链添加的方法是公有方法(实例化的对象可以访问)今天就到这里,明天不见不散收集整理了一套js进阶教程,公众号后台回复“js进阶”即可领取参考文献:《javascript高级程序设计》(第三版)《javascript设计模式》《javascript语言精粹》(修订版)原文链接