js面对对象编程(二):属性和闭包
来源:互联网 发布:如何提升淘宝宝贝权重 编辑:程序博客网 时间:2024/06/04 18:09
上篇博客中讲解了一些js对象的基本概念和用法,这篇博客讲解一下js属性方面的:公有属性,私有属性,特权方法。
如果学过java,公有属性,私有属性,特权方法(即可以访问和设置私有属性的方法)一定很熟悉,那么让我们来看看在js里如何实现呢?
1、公有属性
首先看公有的第一层意思是可以被大家所访问的,对外开放的属性,是相对于私有属性而言的:
function Person(name,age){this.name=name;this.age=age;this.getName=function(){return this.name;}this.getAge=function(){return this.age;}}var josh=new Person('josh','25')console.log(josh.name); //joshconsole.log(josh.getName()); //josh
我们在这里定义了一个叫josh的Person对象,让我们通过new方法再创建2个其他Person对象
var Eric=new Person('Eric','25');var mongo=new Person('mongo','23');console.log(Eric.name); //Ericconsole.log(mongo.name); //monge这里我们每次new一个对象的时候,Person中所有的代码都会复制一份,便造成了内存的浪费,可以通过定义同一类对象共有的方法来解决这个问题,因此在这里需要prototype关键字来我们。
从字面上来看,prototype可以理解为"property to type",即类型的属性,对于一类的属性,拿上面定义的Person来说,即对Person这一类对象共有的方法或属性,我们改造一下上面的代码
function Person(name,age){this.name=name;this.age=age;}Person.prototype.getName=function(){return this.name;}Person.prototype.getAge=function(){return this.age;}var josh=new Person('josh','25')var Eric=new Person('Eric','25');var mongo=new Person('mongo','23');console.log(josh.getName()); //joshconsole.log(Eric.name); //Ericconsole.log(mongo.name); //monge
因此公有方法或属性,也可以理解为通过构造函数的prototype添加的方法或属性,这里的构造函数即Person,由于js中不存在类的概念,所以我们通过构造函数来创建新的对象,而通过prototype定义的属性方法,为这一类所共享,像极了java中类里的静态方法或属性为一类所共享。
2、私有属性
基于面对对象的封装特性,我们并不想把所有变量都公开给外界,于是拿上面的Person对象来说,我们把属性定义中的this.name被换成了var name,于是可以被外界访问的公有属性就变成了私有属性,对于属性的访问结果也变成了undefined
function Person(name,age){//this.name被换成了var namevar name=name;var age=age;}var josh=new Person('josh','25')var Eric=new Person('Eric','25');var mongo=new Person('mongo','23');console.log(josh.name); //undefinedconsole.log(Eric.name); //undefinedconsole.log(mongo.name); //undefined
为什么this.name被换成了var name,对象属性就由公有变私有了呢?首先看this关键字,this表示当前属性所存在的对象:
function Person(name,age){this.name=name;this.age=age;}上面这段代码换成了下面这段,您就可以看明白了,即首先定义一个Person空构造函数,然后定义person对象,再根据person动态增减属性的特性增加name和age属性
function Person(){}var person=new Person();person.name='josh';person.age='25';
那么换成var name的私有属性又是如何实现的呢?这里就要设计js面对对象的几个重要基础概念了,分别是 作用域,上下文,闭包。
首先说作用域,大家如果接触过一门编程语言就应该有了解,作用域是当前定义的变量可以再什么样的范围内被引用。拿大家比较比较熟悉的java来说,java是块级的,在if、while这些块中定义的,只能在块里用,出了块就不行了;如果想范围大一些,可以在方法的开始定义,供整个方法是用,但在方法外不能被是用;也可以定义类级的,在整个类内都能引用。
在js中,作用域是函数级的,也就是在函数内定义的变量,在函数外不可引用,函数起到了界定作用域的作用。上文的这个例子中,对于josh.name属性的访问就变成了undefined。
function Person(name,age){//this.name被换成了var namevar name=name;var age=age;}var josh=new Person('josh','25');console.log(josh.name); //undefined
接下来解释上下文,上下文表明了函数或者对象处在的环境,这个环境中包含了一些变量,对象或者函数。结合作用域的概念一起看一张图
对着这张图来说,person对象可以访问上下文中的变量,对象或者是函数,而上下文中的变量不能访问Person对象的name属性,因为name属性的作用域是局限在person对象内的,也就是外层对内层开放,内层对外层关闭。
那么由此就衍生出了闭包的概念,闭包就是一个封闭的包,能拒绝外层的访问,上图person对象就是一个闭包,包外不能访问包内私有的变量,只能通过某些特殊方式(特权方法)来访问。接下来介绍下特权方法。
3、特权方法
特权方法相当于java类中对私有变量提供访问和设置的get/set方法
function Person(){//在私有属性前加下划线,表示私有属性var _name;var _age;this.getName=function(){return _name;}this.getAge=function(){return _age;}this.setName=function(name){_name=name;}this.setAge=function(age){_age=age;}}var josh=new Person();josh.setName('josh');josh.setAge('25');console.log(josh.getName()); console.log(josh.getAge());
到此,共有属性,私有属性,闭包的概念就讲完了,本篇博客用很小的篇幅将了闭包这个概念,但却说明了闭包最根本的实质,函数所处的上下文没有权利访问函数内定义的变量,于是就形成了闭包(一个封闭的包)。大家有了这个概念,再看闭包的文章,一定会很受用。
- js面对对象编程(二):属性和闭包
- js面对对象编程
- js 面对对象编程
- js的面对对象编程
- 面对对象编程总结(二)
- js---闭包和面向对象编程
- 11. 面对对象编程
- 面对对象编程初步
- 面对对象编程介绍
- 面对对象编程
- JavaScript面对对象编程
- 面对对象编程
- JS:对象和属性
- js-Node对象属性二
- 使用JS闭包控制对象属性访问范围
- js函数--闭包和this对象
- 函数和面对对象
- 类的接口和面对对象编程的添加复杂度
- 规范定义的错误码
- 编程算法 - 连续子数组的最大和 代码(C)
- HTML文档类型
- 121_leetcode_Wildcard Matching
- [hdu 1071]The area 高斯消元
- js面对对象编程(二):属性和闭包
- ORACLE锁机制
- 依赖注入的方式
- 机器学习中的相似性度量
- 游戏中常用算法
- C语言的本质(3)——整数的本质与运算
- 用Java统计字符串中的字母、数字、空格和其他字符
- C语言的本质(4)——浮点数的本质与运算
- C语言的本质(5)——类型转换的本质与处理