前  言

JRedu

 上一篇博客中,我们介绍了JS中的面向对象,并详细的解释了this的指向问题。本篇博客,我们继续来学习JS的面向对象。来深入理解一下JavaScript OOP中的成员属性/方法、静态属性/方法、原型属性/方法,并且一起来探讨一下JS中的原型与原型链。

一 成员属性与成员方法

在构造函数中,通过this.属性声明。或者实例化出对象后,通过“对象.属性”追加的。都属于成员属性、或成员方法;也叫实例属性与实例方法

成员属性/方法,是属于实例化出的这个对象。通过"对象.属性"调用

代码实例

function Person(name){
        this.name = name;// 声明成员属性
        this.say = function(){}// 声明成员方法
    }
    var zhangsan = new Person("张三");
    zhangsan.age = 14; // 追加成员属性
    alert(zhangsan.name);// 调用成员属性
    zhangsan.say();// 调用成员方法
二 静态属性与静态方法

通过"类名.属性名" ,"类名.方法名"声明的变量,成为静态属性、静态方法;也叫类属性、类方法

类属性/类方法,是属于类的(属于构造函数的),这类属性或方法必须通过"类名.属性"调用,而不同通过对象名调用。

代码实例

function Person(name){
}
Person.sex = "男";  // 声明类属性
alert(Person.age); // 调用类属性
var zhangsan = new Person("张三");
alert(zhangsan.sex); // 无法调用。类属性只能用类名调用。
三 私有属性与私有方法

在构造函数中,通过var声明的属性,成为私有属性。

私有属性的作用域,仅在当前函数有效。对外不公开,即通过对象/类都无法调用到。

代码示例

function Person(name){
        var sex = "男";
        alert(sex); // 私有属性只能在类内容使用。
    }
    alert(Person.sex); // 无法调用。私有属性只能在类内容使用。
    var zhangsan = new Person("张三");
    alert(zhangsan.sex); // 无法调用。私有属性只能在类内容使用。
四 Android 事件基础知识

写在了构造函数的prototype上。当使用构造函数实例化对象事,该属性方法会进入新对象的__proto__上。

代码示例:

function Person(){
    }
    Person.prototype.name4 = "name4";// 声明原型属性
    Person.prototype.say = function(){
    } //声明原型方法
    var zhangsan = new Person();
    alert(zhangsan.name); // 可以使用对象调用原型属性
    zhangsan.say(); //可以使用对象调用原型方法

通过上述代码示例,我们可以发现:原型属性和原型方法、成员属性和成员方法,都可以使用对象名调用。那么,成员属性和原型属性到底有什么不同。我们先来看这样的一幅图:

看出点门道了吗? 成员属性是直接声明在对象自身上!! 而原型属性是声明在对象的__proto__上!!!在我们使用“对象名.属性名”访问一个属性时,会先访问成员属性,如果成员属性中找不到,JS会沿着对象的原型链,继续通过__proto__向上查找,也就找到了原型属性。 这就是我们可以使用“对象名.属性名”访问成员属性和原型属性的原因。

但是,说了这么多,什么是__proto__?什么是prototype?什么又是原型链?接下来,我们就讲解一下JS 面向对象中最重要的一环——原型与原型链。

五 Android 事件基础知识

1__proto__ 与 prototype

要讲解原型与原型链,首先,我们要了解两个基本概念——__proto__和prototype。

①  prototype(函数的原型对象):函数才有prototype,而且所有函数必有prototype。prototype是一个对象,指向了当前构造函数的引用地址呢。

②  __proto__(对象的原型):对象才有__proto__,而且所有对象必有__proto__属性(这里的对象除了我们理解的狭义对象,也包括了函数、数组等对象)。当用构造函数实例化(new)一个对象时,会将新对象的__proto__属性,指上构造函数的prototype。

来看个案例

function Person(){
    }
    var zhangsan = new Person();
console.log(zhangsan.__proto__ == Person.prototype); // true
//【解释】上例中,我们使用函数Person,new出了一个对象zhangsan。 那么对象zhangsan的__proto__就等于函数Person的prototype。

2原型链

上面我们介绍了对象的__proto__和函数的prototype。知道了对象的__proto__指向了函数的prototype。那么,我们也说了,函数的prototype本身也是个对象,是对象肯定也有__proto__,那他的__proto__指向了谁? 顺着这个问题,我们延着一个对象__proto__向上查找,这条线路就是我们所说的原型链。

所以,要研究原型链的走向,其实就是研究各种类型对象的__proto__到底指向谁。还记得上篇博客的“杰小瑞this五大准则”吗? 这次,贴心的杰小瑞老师又为大家准备了“杰小瑞原型链四大法则”,一起来看看吧!

杰小瑞原型链四大准则】

① 通过构造函数,new出的对象,新对象的__proto__指向构造函数的prototype

② 所有函数的__proto__ 指上Function()的prototype

③ 非构造函数new出的对象( {}  new Object() 对象的prototype)的__proto__指向Object的prototype

④ Object的prototype的__proto__指向null

字不如表,表不如图。我们一起以一段代码为例,探讨一下原型链。

代码

function Person(){
}
    var zhangsan = new Person();

就是这样一个简单的类new出对象,我们来探讨一下原型链吧~上图!!!

原型链图(杰小瑞老师亲情手绘,亲,点个赞呗!):

六 成员属性与原型方法

说了这么多,我们应该能够理解原型与原型链,也深刻的理解了原型属性、原型方法。 那么问题来了,既然成员属性/方法和原型属性/方法,都能通过对象名访问。我们到底用那种比较好呢?

习惯上,我们会将属性写为成员属性,而方法写为原型方法

原因如下

① 实例化出对象后,所有属性直接在对象上,所有方法都在__proto__上,非常直观清晰。

② 方法写到prototype上,要更加节省内存;

③ 使用for in 循环时,会将对象以及对象原型链上的所有属性和方法打印出来,而方法往往是不需要展示的。 将方法写到__proto__上,可以使用hasOwnProperty将原型上的方法过滤掉、不显示。

④ 官方都这么写。

七 prototype扩展内置函数

那原型还有什么作用呢? 还有一个最常用的,就是我们使用prototype扩展内置函数的方法。可以直接使用内置函数的对象,调用我们扩展的方法;

比如,为Array类添加一个find(val)方法,当一个Array对象调用该方法的时候,如果能找到val值,则返回其下标,否则返回-1。

Array.prototype.find = function(val){ // 在Array类的原型上添加扩展方法find
        for (var i = 0; i<this.length;i++) {
            if(this[i]==val){
                return i;
            }
        }
        return -1;
    }
    var arr = new Array(1,2,3,4,5);
alert(arr.find(1));// 直接使用Array类的对象,也就是数组,就可以调用这个方法

好了,今天的课程就先到这里吧?我们学习了JS中的成员属性、静态属性、原型属性、私有属性等各种学习。 也学习了JS面向对象中非常重要的一个环节——原型与原型链。你都学会了吗? 如果有问题欢迎大家评论留言哦~~我们下次课再见吧!

作者:杰瑞教育
出处:http://www.cnblogs.com/jerehedu/ 
版权声明:本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

技术咨询:

JavaScript面向对象(二)——成员属性、静态属性、原型属性与JS原型链的更多相关文章

  1. Javascript面向对象二

    Javascript面向对象二 可以通过指定原型属性来对所有的对象指定属性, Object.prototype.name="zhangsan"; Object.prototype. ...

  2. JavaScript 面向对象(二) —— 案例篇

    看案例前可以先看看基础篇:JavaScript 面向对象(一) —— 基础篇 案例——面向对象的选项卡:把面向过程的程序一步步改成面向对象的形式,使其能够更加的通用(但是通用的东西,一般会比较臃肿). ...

  3. python 面向对象(二)成员

    ##################################总结########################### 类的成员: 变量: 实例变量      对象.属性=xxx 类变量    ...

  4. JavaScript面向对象之get和set设置读写属性

    之前我们通过this和prototype申明的属性都是可读写的属性,如果想实现单独控制,就必须使用get和set存取期. 基本方法的 步骤一般包含两个步骤,1,使用var关键字定义一个私有属性作为中间 ...

  5. javascript面向对象(二):构造函数的继承

    本文来自阮一峰 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有 ...

  6. 疯狂java学习笔记之面向对象(二) - 成员变量与局部变量

    Java变量按其作用域可分为:成员变量和局部变量.注意:在Java中是没有全局变量这个概念的 一.成员变量: 成员变量是在类中定义的变量,具体可分为类变量与实例变量--有无static修饰 实例变量的 ...

  7. javascript面向对象编程笔记

    对象:一切事物皆是对象.对象是一个整体,对外提供一些操作.比如说一个收音机是一个对象,我们不需要知道它的内部结构是什么,只需要会使用外部的按钮就可以使用收音机. 面向对象:面向对象语言的标志是他们都有 ...

  8. JavaScript 面向对象(三) —— 高级篇

    JavaScript 面向对象(一) —— 基础篇 JavaScript 面向对象(二) —— 案例篇 一.json方式的面向对象 首先要知道,js中出现的东西都能够放到json中.关于json数据格 ...

  9. JavaScript 面向对象(一) —— 基础篇

    学好JS的面向对象,能很大程度上提高代码的重用率,像jQuery,easyui等,这篇博客主要从细节上一步步讲JS中如何有效地创建对象,也可以看到常见的创建对象的方式,最后也会附上一些JS面向对象的案 ...

随机推荐

  1. 初学Python(二)——数组

    初学Python(二)——数组 初学Python,主要整理一些学习到的知识点,这次是数组. # -*- coding:utf-8 -*- list = [2.0,3.0,4.0] #计算list长度 ...

  2. 52. leetcode 96. Unique Binary Search Trees

    96. Unique Binary Search Trees Given n, how many structurally unique BST's (binary search trees) tha ...

  3. Dapper入门教程(三)——Dapper Query查询

    介绍 查询方法(Query)是IDbConnection的扩展方法,它可以用来执行查询(select)并映射结果到C#实体(Model.Entity)类 查询结果可以映射成如下类型: Anonymou ...

  4. struts2上传文件类型列表

    '.a'      : 'application/octet-stream',         '.ai'     : 'application/postscript',         '.aif' ...

  5. Git时光机穿梭

    我们已经成功地添加并提交了一个readme.txt文件,现在,是时候继续工作了,于是,我们继续修改readme.txt文件,改成如下内容: Git is a distributed version c ...

  6. selenium+python开发环境的搭建

    web 调试工具介绍和开发环境搭建 python与selenium开发环境搭建: 一.下载python软件:https://www.python.org/ 下载完后,进行安装,安装成功后,打开IDLE ...

  7. 流畅python学习笔记:第十七章:并发处理

    第十七章:并发处理 本章主要讨论Python3引入的concurrent.futures模块.在python2.7中需要用pip install futures来安装.concurrent.futur ...

  8. Oracle存储过程和函数使用方法

    一.存储过程(PROCEDURE) 使用过程, 不仅可以简化客户端应用程序的开发和维护,而且可以提高应用程序的运行性能.  CREATE [OR REPLACE] PROCUDURE procedur ...

  9. RMAN备份-未使用catalog-控制文件丢失

    情况描述 客户报告数据库故障,新来的系统管理员误操作.删掉了一些文件.具体情况是:删掉了所有重要数据文件.所有控制文件.数据库原来是归档模式,用rman备份数据,而rman 使用控制文件. 幸运的是, ...

  10. leetcode First Bad Version(二分查找)

    You are a product manager and currently leading a team to develop a new product. Unfortunately, the ...