`

js封装、构建对象

 
阅读更多
一、通过闭包,执行匿名函数,返回一个对象
//例1
var Test = function(){
    var a = 1;  //在这里定义的变量,比如a、b、c、d,在整个Test下都可以访问到
    var b = 10;
    var c;
    function hhh(){
        a = 2;
        b = 20;
        //对于a、b、c等变量的处理...
    }
    return{
        a:a,//只能获取a刚定义时的值1,而不能获取程序在运行中实时a的值,不要使用这种写法
        getB:function(){
            return b;//可以获取程序在运行中b实时的值20;(正确的写法)
        }
    }
}();//()是执行函数的运算符(此处是执行一个匿名函数,然后返回一个对象)
Test是一个对象,可以为对象添加属性:Test.d = 30; 此时,在外界就可以通过Test.d获取值。

//例2
var person = function(){      
    var name = "default";//变量作用域为函数内部,外部无法访问
    return {   
       getName : function(){   
           return name;   
       },   
       setName : function(newName){   
           name = newName;   
       }   
    }   
}();   
alert(person.name);    //直接访问,结果为undefined   
alert(person.getName());  //default
person.setName("gerry"); 
alert(person.getName());  //gerry


二、直接调用函数,返回一个对象
//例1
function Point(left, top){   
    this.left = left;//注意:此处的this是指向window对象的,this===window为true!先把值存储在window对象的一个属性中,再取出来
    this.top = top;   
    //handle the left and top...
    return {x: this.left, y:this.top};   
} 
直接动态的构建一个新的匿名对象返回即可:
var pos = Point(3, 4);  //pos.x = 3; pos.y = 4;  

//例2
function Person(){   
    var name = "default"; 
    return {
       getName : function(){   
           return name;   
       },   
       setName : function(newName){   
           name = newName;   
       }
    }   
};
var john = Person();   
alert(john.getName());  //打印default 
john.setName("john");   
alert(john.getName());  //打印john
alert(john.constructor)  //john只是普通的对象,输出function Object(){[native code]}
    
var jack = Person();   
alert(jack.getName());  //打印default
jack.setName("jack");   
alert(jack.getName());  //打印jack
由此代码可知,john和jack都可以称为是Person这个类的实例,因为这两个实例对name这个成员的访问是独立的,互不影响


三、定义对象的“类”:原型,然后使用new操作符来批量的构筑新的对象
//定义一个"类",Address   
function Address(street, xno){   
    this.street = street || 'Shanghai Road';   
    this.xno = xno || 135;   
    this.toString = function(){   
        return "street : " + this.street + ", No : " + this.xno;      
    }   
}   
//定义另一个"类",Person   
function Person (name, age, addr) {   
    this.name = name || 'unknown';   
    this.age = age;   
    this.addr = addr || new Address(null, null);   
    this.getName = function(){return this.name;}   
    this.getAge = function(){return this.age;}   
    this.getAddr = function(){return this.addr.toString();}   
}   
//通过new操作符来创建两个对象,注意,这两个对象是相互独立的
var jack = new Person('jack', 26, new Address('Qing Hai Road', 123));   
var gerry = new Person('gerry', 25);   
//查看结果   
alert(jack.getName());  //打印jack
alert(jack.getAge());   //打印26
alert(jack.getAddr());  //打印street : Qing Hai Road, No : 123
alert(gerry.getName()); //打印gerry
alert(gerry.getAge());  //打印25
alert(gerry.getAddr()); //打印street : Shanghai Road, No : 135


对new操作符进行讲解
我们来看一个例子:
function Shape(type){   
    this .type = type || "rect" ;   
    this .calc = function (){   
       return "calc, " + this .type;   
    }   
}   
    
var triangle = new Shape("triangle");   
alert(triangle.calc());  //打印 calc, triangle
alert(triangle.constructor==Shape);//true
alert(triangle.prototype);  //undefined
    
var circle = new Shape("circle");   
alert(circle.calc());   //打印 calc, circle

在javascript中,通过new操作符来作用与一个函数,实质上会发生这样的动作: 
首先,创建一个空对象,然后用函数的apply方法,将这个空对象传入作为apply的第一个参数,及上下文参数。这样函数内部的this将会被这个空的对象所替代:
var triangle = new Shape("triangle");   
//上一句做了以下两行代码的工作:   
var triangle = {};   
Shape.apply(triangle, ["triangle"]); 
 
当我们使用new操作符时,javascript会:
1、生成一个空对象{} 
2、执行构造函数(实际上就是普通函数),将函数中的this用刚生成的空对象代替,相当于给刚生成的空对象添加属性及值,完成成员设置等初始化工作。即:生成的对象被new后面的方法(函数)的this关键字引用!然后在方法中通过操作this,就给这个新创建的对象相应的赋予了属性.然后返回这个经过处理的对象. 
3、初始化对象(实际上现在已经有了属性,是构造函数赋予的)的constructor属性,让他的值为构造函数(函数也是对象)。所以创建对象的时候没有初始化prototype,而是初始化了constructor,指向构造函数。
 
这样上面的例子就很清楚:先创建一个空对象,然后调用Shape方法对其进行赋值,返回该对象,最后再初始化对象的constructor属性,这样我们就得到了一个triangle对象.
 
对象建立之后,对象上的任何访问和操作都只与对象自身及其原型链上的那串对象有关,与构造函数再扯不上关系了。换句话说,构造函数只是在创建对象时起到介绍原型对象和初始化对象两个作用。
 
例如:
var p = new Person();
此时,p会含有一个constructor属性,指向它的构造函数Person   p.constructor==Person
p.constructor.prototype.age  //p.constructor.prototype即是 构造函数的prototype属性对应的prototype对象


由于带返回值的构造函数会产生奇怪的结果,因此一般最好不要在构造函数中return sth;(空return可以)
这里有说明:http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this

参考:http://abruzzi.iteye.com/博客中的“javascript内核系列”
分享到:
评论

相关推荐

    用javascript写的计算器,封装成对象了(带用例)

    在JavaScript编程中,将功能封装成对象是一种常见的代码组织方式,可以提高代码的复用性和可维护性。在这个场景中,我们讨论的是一个基于JavaScript实现的计算器,它已经被封装为一个对象,便于调用和使用。以下是这...

    国内外javascript经典封装

    通过学习和运用这些经典的JavaScript封装技术,开发者不仅能提升代码质量,还能跟上技术发展趋势,确保项目在未来的可扩展性和兼容性。同时,理解并熟练掌握封装原则,也是成为一名优秀JavaScript开发者的重要一步。

    国内外 JavaScript 经典封装

    10. **前端框架**:React、Vue.js、Angular等,提供了组件化开发模式,封装了DOM操作,优化了性能,简化了单页面应用的构建。 11. **动画库**:如GSAP(GreenSock Animation Platform)、Animate.css,提供强大的...

    JS封装和继承-入门级

    总的来说,JavaScript虽然没有内置的类机制,但它通过原型、构造函数和函数等机制实现了封装和继承,使得开发者可以构建复杂、模块化的应用。理解和熟练掌握这些概念对于JavaScript开发至关重要。

    js 面向对象实例

    在JavaScript面向对象的上下文中,我们可以创建专门处理Canvas绘图的类,封装复杂的绘图逻辑: ```javascript class Circle { constructor(x, y, radius) { this.x = x; this.y = y; this.radius = radius; } ...

    JS封装动态树

    在本项目中,"JS封装动态树"指的是利用JavaScript来创建一个可以动态展示多级树状结构的功能。这样的功能在很多场景下都非常实用,例如组织结构展示、文件目录浏览、导航菜单等。 在实现3级树功能时,我们需要考虑...

    Cesium-demo学习三维,学习JS封装Cesium

    在本项目中,我们将学习如何结合Cesium和Vue.js,通过编写JavaScript代码来封装Cesium功能,创建一个3D地图应用。 首先,我们通过`vue add vue-cli-plugin-cesium`命令添加了Vue CLI插件,该插件是专门为Vue项目...

    Javascript经典封装代码

    JavaScript,作为全球最广泛使用的编程语言之一,是构建动态网页和交互式应用的关键技术。"JavaScript经典封装代码"集合了开发者们在实践中总结出的一些高效、实用的代码片段,旨在提高开发效率,优化代码结构,增强...

    Utiljs一些很实用的javaScript函数封装集合

    Util.js 是一个非常实用的JavaScript库,它封装了一系列常见的功能函数,旨在简化开发过程,提高代码的可复用性和效率。这个库涵盖了多种类别,包括处理数组、浏览器特性、日期操作、函数辅助、数学计算、媒体操作、...

    JavaScript学习笔记_js常用函数封装_js包.zip

    本压缩包“JavaScript学习笔记_js常用函数封装_js包.zip”包含了对JavaScript基础及进阶技巧的学习资料,特别关注了函数封装和模块化开发实践。 首先,`tool.js`可能是一个实用工具函数集合,封装了一些常见的...

    表单数据自动封装到javaBean中

    当前,许多Web应用采用前端框架(如Angular、React或Vue.js)进行视图层的构建。这些框架同样支持数据绑定,可以与后端的JavaBean进行交互。例如,Angular的`ngModel`指令可以将表单字段与模型对象关联,提交时自动...

    C++调用JS封装类库2

    "C++调用JS封装类库2"这个主题聚焦于如何使用C++来调用JavaScript的函数和对象,以实现两者之间的通信。这通常涉及到一系列的技术和工具,如JavaScript引擎(如V8或SpiderMonkey)、绑定库(如Nan或JSCPP)以及接口...

    JavaScript面向对象技术实现树形控件

    在JavaScript中,虽然原生的HTML不直接支持树形控件,但通过编写JavaScript脚本,我们可以利用其面向对象的特性来构建这样的控件。面向对象编程的三大核心概念——继承、封装和多态性,在JavaScript中都能找到相应的...

    javascriptAPI教程及常用封装

    在JavaScript中,我们可以使用函数、对象、类等结构进行封装。模块化工具,如CommonJS(在Node.js中使用)和ES6的import/export,进一步促进了代码的组织和重用。 在实际项目中,我们经常需要借助第三方库和框架,...

    百度地图javascript API + 调用封装javascript

    "工具"可能意味着这个封装后的API可以作为一个开发工具,帮助开发者快速构建地图相关的应用。 **内容详解:** 在使用百度地图JavaScript API时,开发者通常需要了解以下几点: 1. **API引入**:首先需要在HTML...

    面向对象JavaScript精要(英文原版pdf)

    - **第七章:混合式编程**:介绍如何结合面向对象编程与其他编程范式(如函数式编程)来构建复杂的系统。 #### 五、读者对象及学习目标 本书适合有一定JavaScript基础的开发者阅读。通过本书的学习,读者可以深入...

    Javascript 面向对象的JavaScript进阶

    ### JavaScript面向对象进阶知识点...通过以上示例和理论分析,我们可以看到面向对象的JavaScript如何通过封装、抽象、继承和多态性等特性来构建更加灵活和可维护的代码结构。这对于开发复杂的Web应用程序至关重要。

    Javascript中的封装与继承

    在这个文档中,我们将深入探讨JavaScript中的封装和继承这两个核心概念,帮助你更好地理解和应用这些知识。 封装是面向对象编程的基本原则之一,它涉及到如何组织和保护代码,以实现数据隐藏和功能模块化。在...

    javascript面象对象编程

    JavaScript中的面向对象编程(Object-Oriented Programming, OOP)是一种设计模式,它允许开发者创建具有封装、继承和多态性的复杂结构。在JavaScript中,虽然没有像Java或C++那样的类关键字,但它通过函数和原型...

    JavaScript面向对象编程指南

    本指南将深入探讨JavaScript中的面向对象特性,包括类、对象、继承、封装和多态性。 1. **对象和对象字面量** JavaScript中的对象是键值对的集合,可以通过对象字面量{}来创建。例如: ```javascript let person...

Global site tag (gtag.js) - Google Analytics