面对对象和prototype继承的理解总结

一些基于自己的理解和总结,如有错误望指出。

1怎么理解构造函数

构造函数:所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会指向实例对象。

构造函数每次实例化都是重新构造。

<script>
    function Person(name,age) {
        this.name = name;
        this.age = age;
        this.showName = function() {
            alert("我的名字是" + name);
        }
        this.showAge = function() {
            alert("我的年龄是"+ age);
        }
    }
    var demo =  new Person("刘德华",18);
    var demo1 = new Person("刘德华",18);
    console.log(demo.showName == demo1.showName);  // false
</script>

返回false是因为this的指向不一样,一个是demo,一个是demo1。

2什么是this

this:this指向的是被调用的函数的调用者(是谁调用了这个函数)和正在执行的事件的对象。

<script>
    function Person(name,age) {
        this.name = name;
        this.age = age;
        console.log(this);
    }
    Person();  // this指向window
    var xiaoming = new Person(); // this指向 xiaoming这个对象
</script>

3prototype和__proto__

prototype(显式原型):每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象,可以理解为prototype(显式原型)是针对于函数来说的。

__proto__(隐式原型):JavaScript中任意对象都有一个内置属性[[prototype]],在ES5之前没有标准的方法访问这个内置属性,但是大多数浏览器都支持通过__proto__来访问。ES5中有了对于这个内置属性标准的Get方法Object.getPrototypeOf(),可以理解为__proto__(隐式原型)是针对对象来说的。

补充: 一个对象的原型也是一个对象,Object.prototype (对象的原型对象)是个例外,它的__proto__值为null。

两者的关系和作用

关系:隐式原型指向创建这个对象的函数(constructor)的prototype。

显式原型的作用:用来实现基于原型的继承与属性的共享。

隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次查找。

4 JS中的new关键字都干了什么?

function Person() {};

var xiaoming = new Person();

new操作符具体干了什么呢,就干了三件事情:

第一,我们创建了一个空对象xiaoming
第二,我们将这个空对象的__proto__指针指向了Person函数的prototype对象。
第三,执行Person这个构造函数,如果Person有返回值(有return)直接将返回值返回给xiaoming实例对象,如果构造函数中没有返回值,就会直接把Person构造函数中的this对象返回给xiaoming实例对象,可以理解为克隆了一份Person构造函数中的this对象,给了xiaoming这个实例对象并保存在计算机内存中。

5原型继承的优点

先理解一下内存的概念

数据通过变量来管理,定义变量的过程其实就是内存分配的过程,所以本质上一切数据都是存放在内存中的,一切变量,包括对象都是在内存中管理的。

实例对象也是一个变量,他也是放在内存中的,当我们实例化一个对象,其实就是将构造函数的属性拷贝一份,同时在内存中开辟一段新的区域保存这些值。

我们定义一个构造函数是不分配内存的,只有实例化的时候才分配内存。

实例对象是如何在内存存储的,指针是什么?

当你实例化一个对象,那么内存会开辟两个内存区域:

一个保存实例的名称变量,其实保存的只是地址,也可以把它理解为指针,它指向的是地址所对应的真正数据,类似于门牌号。

另一个保存对象的真正数据。

基于上面的理论,可以来谈谈用原型继承的优点了

构造函数不论被实例化多少次,它的原型对象都只会生成一次,实例化的时候只拷贝构造函数中的属性,而不会拷贝构造函数原型对象的属性。

当我们new一个实例对象时,其中的一个作用就是让实例对象的原型指针指向构造函数的原型,所以实例对象的原型中保存的并不是从构造函数原型中继承的所有内容,而只是一个地址,一个指针。构造函数原型对象的内容并不会被拷贝一份给实例对象。这样一来,就节约了内存空间。

总而言之,构造函数实例化后,实例对象的原型都指向的是同一个原型,即是这个构造函数的原型。

通过下面这个例子理解一下:

<script>
    function Person(name,age) {
        this.name = name;
        this.age = age;
        this.showAge = function () {
            alert("我的年龄是"+ this.age);
        };
    }
    Person.prototype.showName = function() {
        alert("我的名字是"+ this.name);
    };

    var demo = new Person("刘德华",15);
    var demo1 = new Person("刘德华",15);

    alert(demo.showName === demo1.showName);  // 返回true
    alert(demo.showAge === demo1.showAge);    // 返回false
</script>

实例化了两个对象demo和demo1,他们的原型都指向的构造函数Person的原型,但是this的指向却是不同的。

6属性屏蔽理论

因为当我们调用一个函数的方法和属性时,先在函数本身里面寻找,找不到就会在函数的原型对象里寻找,如果原型对象中和构造函数中有相同的属性的话,就会显示构造函数中的属性。

我们想访问原型中的被屏蔽掉的属性有两种方法:

1.delete

2.使用Product.prototype.属性或者方法名称

    function Product(){
        this.name=‘神仙‘;
        this.description = ‘‘
        this.buy = function(){
            alert(‘构造函数对象‘)
        }
    }

        Product.prototype={
            name:‘魔鬼‘,
            buy:function(){
                alert(‘原型对象‘)
            }
        }

        var product = new Product()
        console.log(product.name)  // 神仙

        /*清除构造函数中的name*/
        delete product.name  // 清除后显示原型对象中的name属性
        console.log(product.name) // 魔鬼
        product.name=‘魔鬼2‘  // 再次给name赋值
        console.log(product.name) // 魔鬼2

        /*没有清除之前,也可以用这种Product.prototype.buy()式来获取原型方法*/
        product.buy(); // 构造函数对象
        Product.prototype.buy();  // 原型对象
        console.log(product.buy) // function (){alert(‘构造函数对象‘)}

        /*清除*/
        delete product.buy
        console.log(product.buy) //function (){alert(‘原型对象‘)}
        product.buy(); // 原型对象

持续补充...

时间: 2024-10-07 12:55:19

面对对象和prototype继承的理解总结的相关文章

javascript面对对象编程 之继承

上一篇博客中为大家介绍了javascript面向对象编程原则的封装,今天为大家介绍继承,在javascript中没有类的概念,所有不能像c#,java语言那样,直接的用类去继承类.比如现在有比如,现在有一个"动物"对象的构造函数. function Animal(){ this.species = "动物"; } 还有一个"猫"对象的构造函数. function Cat(name,color){ this.name = name; this.co

16、python面对对象之类和继承

前言:本文主要介绍python面对对象中的类和继承,包括类方法.静态方法.只读属性.继承等. 一.类方法 1.类方法定义 使用装饰器@classmethod装饰,且第一个参数必须是当前类对象,该参数名一般约定为“cls",通过它来传递类的属性和方法 (不能传递实例属性和实例方法),跟实例方法的self用法相似. 2.类方法的调用 实例对象和类对象都可以调用 3.应用场景 在需要站在类的角度执行某个行为时,那么就可以定义为类方法 class Student: def __init__(self,

面对对象特征之继承

1.什么是继承? 使一个类拥有另一个类全部公开的属性与行为的一种机制. 2.继承的目的 假如一个类拥有另一个类的全部行为与属性,并且这些属性与行为数量较大,同时为其他类所共享,可以将这个类定义为子类去继承另一个类,实现代码复用. 3.继承的影响 子类拥有了父类中非private的方法与属性. 4.继承的限制 构造方法:任何一个类中都有一个默认的无参构造方法,一旦显式地创建了有参构造方法,默认的无参构造方法就被清除.子类的无参与有参构造方法中默认调用父类的无参构造方法,如果父类中不存在无参构造方法

Android 内功心法(番外)——写在设计模式前,面对对象编程基础

我写的一系列"Android 内功心法"着重讲到android中经常使用的设计模式.那么如果有些程序员刚刚接触设计模式,那就有必要确定一下自己面对对象编程的基础是否牢固了. 因为这直接关系到你阅读设计模式的速度和理解质量. 接下来我将简单介绍java中面对对象编程的一些基础知识. 1,类和修饰符 public class ClassTest{ public ClassTest{ } public void test(){ } } 其中类的定义是以"class"来决定

关于面对对对象之接口的通俗理解

一些人写代码,按照计算机思考的那个模式写,写出来的代码,能实现功能,但是拓展性不好,而有些人写代码,是按照人看世界的那些思路去写,写出来的代码 看起来像那么回事儿,而且也非常的符合逻辑,这是为什么?为什么同样是写代码,为什么写出来的东西会完全不一样了? 最近一直在反思自己写的代码,以前写,都是为了完成某项功能而写,写完了也就完事儿了,可是最近却不是这样了,最近想打问题是,写代码是不是只要在实现功能的层面上就可以了了?后来得出的答案是,代码其实还可以写的更加的灵活多变一点的 那么今天我们就来谈谈关

39.C#--面对对象构造函数及构造函数继承使用

//一.新建Person类namespace _39.面对对象构造函数及构造函数继承使用{public class Person{//字段.属性.方法.构造函数//字段:存储数据//属性:保护字段,对字段的取值和设值进行限定//方法:描述对象的行为//构造函数:初始化对象(给对象的每个属性依次的赋值)//类中的成员,如果不加访问修饰符,默认都是privateprivate string _name; //字段public string Name //属性{get { return _name;

javascript 之 prototype继承机制

理解Javascript语言的继承机制 javascript没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承. 1.引言 1994年,网景公司急需一种网页脚本语言,使得浏览器可以与网页互动.工程师Brendan Eich 负责开发这种新语言.他觉得,没必要设计得很复杂,这种语言只要能够完

JavaScript对象创建,继承

创建对象 在JS中创建对象有很多方式,第一种: var obj = new Object(); 第二种方式: var obj1 = {};//对象直面量 第三种方式:工厂模式 function Person(){ var obj = new Object(); obj.name = 'xxx'; obj.age = 12; return obj; } var p1 = Person(); typeof p1 ;// object 第四种方式:构造函数模式 var Person = functio

js面对对象编程(二):属性和闭包

上篇博客中讲解了一些js对象的基本概念和用法,这篇博客讲解一下js属性方面的:公有属性,私有属性,特权方法. 如果学过java,公有属性,私有属性,特权方法(即可以访问和设置私有属性的方法)一定很熟悉,那么让我们来看看在js里如何实现呢? 1.公有属性 首先看公有的第一层意思是可以被大家所访问的,对外开放的属性,是相对于私有属性而言的: function Person(name,age){ this.name=name; this.age=age; this.getName=function()