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


    上篇博客中解说了一些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);  //josh
    console.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);  //Eric
    console.log(mongo.name);  //monge
            这里我们每次new一个对象的时候。Person中全部的代码都会复制一份,便造成了内存的浪费。能够通过定义同一类对象共同拥有的方法来解决问题。因此在这里须要prototypekeyword来我们。

            从字面上来看。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()); //josh
    console.log(Eric.name);  //Eric
    console.log(mongo.name);  //monge

             因此公有方法或属性,也能够理解为通过构造函数的prototype加入的方法或属性,这里的构造函数即Person。由于js中不存在类的概念,所以我们通过构造函数来创建新的对象,而通过prototype定义的属性方法。为这一类所共享,像极了java中类里的静态方法或属性为一类所共享。


    2、私有属性

            基于面对对象的封装特性。我们并不想把全部变量都公开给外界,于是拿上面的Person对象来说,我们把属性定义中的this.name被换成了var name。于是能够被外界訪问的公有属性就变成了私有属性,对于属性的訪问结果也变成了undefined

    function Person(name,age){
    	//this.name被换成了var name
    	var 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); //undefined
    console.log(Eric.name);  //undefined
    console.log(mongo.name);  //undefined

    为什么this.name被换成了var name,对象属性就由公有变私有了呢?首先看thiskeyword。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 name
    	var 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());

              到此。共同拥有属性,私有属性,闭包的概念就讲完了,本篇博客用非常小的篇幅将了闭包这个概念,但却说明了闭包最根本的实质,函数所处的上下文没有权利訪问函数内定义的变量。于是就形成了闭包(一个封闭的包)。大家有了这个概念,再看闭包的文章,一定会非常受用。









  • 相关阅读:
    7.4mybatis整合ehcache(mybatis无法实现分布式缓存必须和其他缓存框架整合)
    Mybatis-利用resultMap 输出复杂pojo
    1.2MyBatis介绍
    1Mybatis入门--1.1单独使用jdbc编程问题总结
    AJAX的来龙去脉(由来)-如何被封装出来的--ajax发送异步请求(四步操作)
    人人权限 添加一张表查询出来
    salesforce lightning零基础学习(九) Aura Js 浅谈二: Event篇
    salesforce lightning零基础学习(八) Aura Js 浅谈一: Component篇
    salesforce lightning零基础学习(七) 列表展示数据时两种自定义编辑页面
    salesforce零基础学习(八十九)使用 input type=file 以及RemoteAction方式上传附件
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10531359.html
Copyright © 2020-2023  润新知