你不知道的JavasScript上篇·第四章·混合对象·类

一、类的理论

1、类的核心概念:多态

  • 是说父类的通用行为可以被子类用更特殊的行为重写

二、类的机制

1、构造函数

类实例是有一个特殊的类方法构造的,这个方法名通常和类名一致;

类构造函数属于类,构造函数大多需要用new来调。

2、类的多态

其实就是子类可以改写父类的同名方法也可以调用继承自父类的同名方法,

任何方法都可以引用继承层次中高层的方法,无论高层的方法名是否相同。

多态的另一个方面是,在继承链的不同层次中一个方法名可以多次被定义,调用方法时会自动选择合适的定义。

多态并不表示子类和父类有关联,子类得到的只是父类的一份副本。

类的继承其实就是复制。

3、混入

模拟类的复制行为,这个方法就是混入。

混入分为两种类型:显示和隐式

  • 显示混入:手动进行复制的。

    下面例子中 Person.eat.call(this) 就是显式多态

 function mixin(sourceObj,targetObj){
     for(key in sourceObj){
        console.log(!(key in targetObj))
         //当Person里有,targetObj里没有的时候才进行复制
         if(!(key in targetObj)){
             targetObj[key] = sourceObj[key]
         }
     }
     return targetObj;
 }
 var Person = {
     sex:‘person‘,
     drink:function(){
         console.log(‘person要喝水‘)
     },
     eat:function(){
         console.log(‘person要吃东西‘)
     }
 }
 var girl = mixin(Person,{
     sex:‘girl‘,
     eat:function(){
         Person.eat.call(this);
         console.log(this.sex+‘要吃东西‘)
     }
 })
 console.log(girl)
 girl.eat();

运行结果如图:

复习上篇内容:

"属性名" in 目标对象:在目标对象上查找属性名也在原型链上也查找

Object.prototype.hasOwnPrototype.call(目标对象,属性名) 只在目标对象上查找属性

这里的
if(!(key in targetObj)){
    targetObj[key] = sourceObj[key]
}
也可以写成
if(!(Objcet.prototype.hasOwnPrototype.call(targetObj,key)){
    targetObj[key] = sourceObj[key]
}
但是因为这里targetObj和souceObj并没有继承关系所以不必用Object.prototype.hasOwnPrototype.call()
  • 寄生继承

    寄生继承是显式混入模式的一种变体,因为他既是显式的又是隐式的

    实例:

   function Animal(){
       this.type = ‘animal‘
   }
   Animal.prototype.color = function(){
       console.log("animal‘s color")
   }
   Animal.prototype.weight = function(){
        this.color();
       console.log("animal‘s weight")
   }
   function Cat(){
       var cat = new Animal();
       cat.type=‘cat‘;
       var anweight = cat.color;
       cat.weight = function(){
           anweight.call(this);
           console.log(this.type+"color" )
       }
       return cat;
   }
   var myCat = new Cat();
   myCat.weight()
  • 隐式混入
    function Something = {
        cool:function(){
            this.greeting = ‘hello world‘;
            this.count = this.count ? this.count+1 : 1 ;
        }
    }
    Something.cool();
    Something.greeting();
    Something.count;
    var  Another = {
        cool:function(){
        //隐式把Something混入Another
            Something.cool.call(this)
        }
    }
    Another.cool();
    Another.greeting;//hello world
    Another.count;//1

这样的结构容易搞不清this,对于方法的引用容易出现问题,一般不从采用这种结构

总结:

类是一种设计模式,也意味着复制。

类被继承时,行为(属性)也会被复制到子类中

多态(在继承链的不同层次名称相同但是功能不同的函数) 看起来似乎是从子类引用父类,但是本质上引用的其实是复制的结果

混入模式可以用来模拟类的复制行为,显式混入实际上无法完全模拟类的复制行为,因为在Js中对象只能复制引用,无法复制被引用的对象或者函数本身(函数也是对象)

原文地址:https://www.cnblogs.com/angfl/p/10220545.html

时间: 2024-11-09 19:39:19

你不知道的JavasScript上篇·第四章·混合对象·类的相关文章

第四章 python对象

4.1 Python 对象 所有的Python 对像都拥有三个特性:身份,类型和值.身份:每一个对象都有一个唯一的身份标识自己,任何对象的身份可以使用内建函数id()来得到.这个值可以被认为是该对象的内存地址.您极少会用到这个值,也不用太关心它究竟是什么. 类型对象的类型决定了该对象可以保存什么类型的值,可以进行什么样的操作,以及遵循什么样的规则.您可以用内建函数type()查看Python 对象的类型.因为在Python 中类型也是对象(还记得我们提到Python 是面向对象的这句话吗?),所

第四章:对象的组合——java并发编程实战

一.设计线程安全的类 找出构造对象状态的所有变量(若变量为引用类型,还包括引用对象中的域) 约束状态变量的不变性条件 建立对象状态的并发访问管理策略(规定了如何维护线程安全性) 1.收集同步需求(找出复合操作.多个变量遵循原子性的操作等) 2.依赖状态的操作(找出操作是否基于先验条件,例:取出当队列不为空) 3.状态的所有权(对象被哪些线程所有,哪些线程可以操作对象) 二.实例封闭 将数据封装在对象内部,可以将数据的访问限制在对象的方法上,确保简单正确的持有锁.(因为无需观察整个程序,只需检查当

python核心编程第四章 python对象

4–1. Python 对象.与所有 Python 对象有关的三个属性是什么?请简单的描述一下.  身份,类型和值. 4–2. 类型.不可更改(immutable)指的是什么?Python 的哪些类型是可更改的 (mutable),哪些不是? 如果对象支持更新操作,那么它的值就可以改变,否则它的值也是只读的.对象的值是否 可以更改被称为对象的可改变性(mutability) 数字 Scalar 不可更改 直接访问 字符串 Scalar 不可更改 顺序访问 列表 Container 可更改 顺序访

学习第四章与第五章的感悟

从第四章开始接触类与对象,了解类的定义,类包括标准类和用户自定义类,通常我们用的都是用户自定义类,在类中可以定义构造器,一个类中最少可以定义一个构造器,构造器与类同名,构造器有一个或多个参数,构造器没有返回值,伴随着new操作一起调用: 类具有三个特性:封装性.多态性.继承性:并且Java允许重载任何方法,不只是构造器方法,如果有多个方法,相同的名字,不同的参数,这样的方法叫做重载:如果在构造器中没有显式的赋初值,会给数值型默认赋值为0,对象引用为null,布尔为false. 在类的继承性中,子

Python核心编程笔记——第四章

第四章 Python对象 1.类型也是对象: a = 4;type(a)-><type 'int'>,这里"<type 'int'>"是一个类型对象(可以赋值给一个变量),可以使用 type(type(a)) 来验证 2.Python2.2开始,类和类型统一,类=类型,实例是类型的对象 3.任何对象都天生具有布尔值 4.整数对象,字符串对象,元组对象都是不可变对象,Python会高效的缓存整数和字符串对象,所以 a=3;b=1+2;(a is b)会返回T

Java-第十四章-代参的方法(二)-编程实现,输入班里10名学生的身高,获得身高最高的学生要求对象数组类型方法

package com.ww.yzpA; public class Students { int No; int Height; } package com.ww.yzpA; public class Height { public Students getMaxHeigth(Students[] str) { Students A = new Students(); for (int i = 0; i < str.length; i++) { if (str[i].Height > A.He

第四章(类、对象和接口)

Kotlin的类和接口与Java的类和接口还是有一点区别的.例如:接口可以包含属性声明.与Java不同,Kotlin的声明默认是 final?和 public?的.此外,嵌套的类默认并不是内部类:它们并没有包含对其外部类的隐式引用. Kotlin中的接口 Kotlin的接口与Java 8中的相似:它们可以包含抽象方法的定义以及非抽象方法的实现.与Java 8不同的是,Java 8中需要你在这样的实现上标注default关键字,而Kotlin没有特殊的注解:只需要提供一个方法体.示例: inter

标准库》第三章 包装对象和Boolean对象

第三部分  标准库 ***************第三章   包装对象和Boolean对象******************* 一.包装对象的定义[1]有人说,JavaScript语言"一切皆对象",数组和函数本质上都是对象,就连三种原始类型的值--数值.字符串.布尔值--在一定条件下,也会自动转为对象,也就是原始类型的"包装对象". 所谓"包装对象",就是分别与数值.字符串.布尔值相对应的Number.String.Boolean三个原生对象

C++ Primer Plus学习:第四章

C++入门第四章:复合类型 1 数组 数组(array)是一种数据格式,能够存储多个同类型的值. 使用数组前,首先要声明.声明包括三个方面: 存储每个元素中值的类型 数组名 数组中的元素个数 声明的通用风格如下: typename arrayname[arrysize]; 注;arrysize指定元素数目,必须是整型常量,不能是变量. 数组的很多用途均基于这样一个事实:可以单独访问数组元素.方法是使用下表或索引对元素进行编号.C++数组从0开始编号,并使用带索引的方括号表示法来指定数组元素. 注