js高级03

目录

面向对象和面向编程

原型

原型链

原型链查找规则

原型链

原型继承

改变 this 指向

new实例化对象过程

面向对象和面向编程

面向过程编程:分析好解决问题所需要的步骤,按照步骤一步步解决问题

面向对象编程:将事务分解成一个一个对象,然后由对象之间分工合作

面向对象编程的优点:灵活性很高,代码可复用,容易维护和开发

面向对象的特性: 1. 封装性 2. 继承性 3. 多态性

构造函数:构造函数体现了面向对象的封装特性,构造函数实例创建的对象彼此独立、互不影响

构造函数存在的问题:使用构造函数来创建大量的对象会存在浪费内存的问题

function Star(uname) {
            this.uname = uname
            this.sing = function() {
                console.log('我喜欢听别人唱歌');
            }
  		}
  		const aa = new Star('好人')
  		const bb = new Star('好人')
  		console.log(aa.sing === bb.sing) // 结果是false,说明两个函数的地址并不一样,会造成内存的浪费

原型:

它是一个对象,我们也称 prototype 为原型对象,主要作用是共享方法

  1. 构造函数通过原型分配的函数是所有对象所共享的
  2. 每一个构造函数都有一个 prototype 属性,指向我们的原型对象
  3. 原型对象上面可以挂载函数,对象实例化不会多次创建原型上的函数,可以节约内存
  4. 构造函数和原型对象中的 this 都指向实例化对象, ---- 这句话不是非常严谨,我们可以说,在对象进行实例化的过程中,构造函数和原型对象中的 this 都指向实例化对象

constructor 属性:每个原型对象里面都有 constructor 属性,该属性指向该原型对象的构造函数

constructor 属性的使用场景:如果有多个对象的方法,我们可以给原型对象采取对象形式的赋值,但是这样就会覆盖掉构造函数原型对象原来的内容,这样修改后原型对象 constructor 就不在指向当前构造函数了,这时我们需要在修改后的原型对象中添加 constructor 指向原来的构造函数。如果不添加该属性的话,当我们打印实例化对象.constructor 的时候打印出来的是构造函数 Object ,原因是实例化对象身上没有 constructor 属性,他会沿着原型链往上查找,实例化对象的构造函数的原型身上也找不到 constructor 属性,接着往上找,找到了顶级对象 Object 的构造函数原型中,有 constructor 属性,指向了顶级对象 Object 的构造函数:

		 function Star(uname) {
            this.uname = uname
        }
        Star.prototype = {
            // 手动利用 constructor 属性指回原来的 Star 构造函数
            constructor: Star,
            sing : function () { console.log('我喜欢听歌');}
        }
        const pzy = new Star('pzy')
        console.log(pzy.constructor); // 指向当前构造函数

对象原型 __ proto __:

对象都会有一个属性 __ proto __ 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数的原型对象的属性和方法,就是因为对象有 __ proto __ 属性的存在,__ proto __ 在浏览器中表示为 [[ prototype ]]

原型链:

原型链查找规则:

1.当访问一个对象的属性和方法的时候,首先查找这个对象自身有没有该属性或者说方法

2.如果没有就查找它的原型,也就是 __ proto __ 指向的 prototype 原型对象

3.如果还没有查找原型对象的原型 (Object的原型对象),直到找到 null 为止

原型链:

原型链中就是实例对象和原型对象之间的链接。每个函数都有一个prototype属性,这个prototype属性就是我们的原型对象,我们拿这个函数通过new构造函数创建出来的实例对象,这个实例对象自己会有一个指针(_ proto_ )指向他的构造函数的原型对象!这样构造函数和实例对象之间就通过( _ proto_ )连接在一起形成了一条链子。

原型继承:

基于构造函数原型对象实现面向对象的继承特性,在我们进行多次实例化对象的时候,一些属性和方法是相同的,我们可以将公共的属性和方法封装在一个函数里面,将这个函数进行实例化然后赋值给构造函数的原型,同时添加 constructor 属性指回当前的构造函数 ---- 父构造函数要在子构造函数中去用 call 调用,同时改变 this 的指向

改变 this 指向:

1. call() : 改变 this 的指向,让 this 指向函数的调用者,同时调用函数,第一个参数指定是this,其余的参数是实参

2. apply() : 改变 this 的指向,同时调用函数,后面传入的实参是以数组的形式,返回值就是函数的返回值

3. bind() : 能改变 this 的指向,但是不会调用函数,返回一个新函数,在事件处理和定时器中经常使用

instanceof:右边变量的 prototype 属性,在左边变量的原型链上就会返回 true,否则返回 false

new实例化对象过程:

1、在内存中创建一个新对象。var obj = varobj = new Object()
2、这个新对象内部的I[Prototype]J(_proto_)特性被赋值为构造函数的prototype属性。obj._proto_ = Star.prototype构造函数内部的 this 被赋值为这个新对象(即this 指向新对象)。Star.cal(obj,uname,age) //Star.apply(obj,arguments)

3、执行构造函数内部的代码(给新对象添加属性)。
4、如果构造函数返回对象,则返回该对象;否则,返回刚创建的新对象(空对象)。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值