zoukankan      html  css  js  c++  java
  • JavaScript对象探讨

    由于JavaScript的灵活性,可以让每个人按照自己的习惯进行编写代码.有函数式的编程方式,也有现在用的较为广泛的对象字面量.由于面向对象的出现,JavaScript刚开始的函数编程也逐渐演化为类式编程方式.现在我对几种比较熟悉的编程习惯进行简单的说明:
    1.对象字面量:
    1. var person = {
    2.         name:null,
    3.         setName:function(name){
    4.                 this.name = name;
    5.                 return this.name;
    6.         },
    7.         getName:function(){
    8.                 alert(this.name);
    9.         }
    10. }
    复制代码

    具有JavaScript特色的一种编程方式,以类为单位含有属性name,方法setName和getName.调用方法比较简便person.setname('R'),this由此至终均指向person,person的属性与方法均不私有,可以进行调用.

    2.prototype构造器调用模式
    1. var Person = function(){
    2.         this.name = null;
    3. }
    4. Person.prototype.setName = function(name){
    5.         this.name = name;
    6. }
    7. Person.prototype.getName = function(){
    8.         alert(this.name);
    9. }
    复制代码

    也是很常见的编程方式,创建一个Person类,然后利用prototype对类进行扩展,添加方法.与对象字面量最大区别在于,调用该类的方法时,必须先new(跟Java调用类相似).var p = new Person();p.getName();如果不用new,而直接创建,会产生错误.而且这种错误将不会报错,难以发现.错误的产生原因来自于this指向Person.prototypel,而Person并没有setName方法.

    3.利用匿名函数进行函数编程
    1. (function(){
    2.         var name;
    3.                   
    4.         var setName = function(n){
    5.                  name = n;
    6.         }
    7.         window['person']['setName'] = setName;
    8.         
    9.         var getName = function(){
    10.                 alert(name);
    11.         }
    12.         window['person']['getName'] = getName;
    13. })()
    复制代码

    类的出现,其中一个最大的好处就是降低了全局变量的出现,但是如果你依旧习惯于函数式编程,没关系,只要创建一个匿名函数,进行闭包,就可以再里面进行函数编程,也不需要担心全局变量的出现.如上所看到的var name;在匿名函数外部是无法调用的,然后利用外部的变量来调用内部的函数,或者是变量.可以借此创建私有变量和私有方法.

    4.类式编程(不知道取什么名)
    1. var person = function(){
    2.         var name = null;
    3.         return{
    4.                 setName:function(n){
    5.                         name = n;
    6.                 },
    7.                 getName:function(){
    8.                         alert(name);
    9.                 }
    10.         }
    11. }
    复制代码

    与对象字面量很相似,其不同之处在于抛开了this,和可以对方法与属性进行私有.调用方法与对象字面量基本一致.

    5.方法链
    1. var Person = function(){
    2.         this.name = null;
    3. }
    4. Person.prototype = {
    5.         setName:function(name){
    6.                 this.name = name;
    7.                 return this;
    8.         },
    9.         getName:function(){
    10.                 alert(this.name);
    11.                 return this;
    12.         }
    13. }
    复制代码

    jQuery就是一个最经典的方法连库,如果还不懂方法链是什么,看看这个例子:
    1.         var p = new Person();
    2.         p.setName('Tom').getName().setName('Ray').getName();
    复制代码

    由于每个方法的结尾都是return this;所以产生了方法链式的类.

    本人比较熟悉的就是这几种方式了,每个人都有每个人的特色,所以方式也是说不尽的.但是借此,我想探讨以下几个问题:
    1.有关于this指针
    在建立多种类的时候都用到this,可是this的作用究竟是什么,而其实this在重用和继承上起着很大的作用.我们先看看一个关于继承的例子:
    首先建立Person类:
    1. var Person = function(){
    2.         this.name = null;
    3. }
    4. Person.prototype.setName = function(name){
    5.         this.name = name;
    6. }
    7. Person.prototype.getName = function(){
    8.         alert(this.name);
    9. }
    10. Person.prototype.getAge = function(){
    11.         var age = this.age || '';
    12.         alert(age);
    13. }
    复制代码


    然后在建立一个Children类,并集成Person的所有方法和属性:
    1. var Children = function(age){
    2.         this.name = null;
    3.         this.age = age;
    4. }
    5. Children.prototype = new Person();        //继承Person的属性和方法
    6. Children.prototype.ageJudge = function(){        //另外为Children添加新方法
    7.         if(this.age > 18){
    8.                 alert('成年人~');
    9.         } else {
    10.                 alert('未满18岁呢~');
    11.         }
    12. }
    13. Children.prototype.getName = function(){        //重写getName方法
    14.         var about = this.name + ' ' + this.age;
    15.         alert(about);
    16. }
    17. var tom = new Children(12);
    18. var ages = tom.getAge();        //12
    19. var judge = tom.ageJudge();        //未满18岁呢~
    20. var setN = tom.setName('Tom');
    21. var get = tom.getName();        //Tom 12
    复制代码

    这就是继承,然后我们看个简单的函数重用:
    1. var SetColor = function(){
    2.         this.style.backgroundColor = '#000';        //this指向window
    3. }
    4. document.body.onclick = SetColor;        //此时this指向body
    5. documnet.getElementById('color').onmouseout = SetColor;                //this指向documnet.getElementById('color')
    复制代码

    看了this的作用之后,想必对this有了新的认识了吧.现在就有疑问了,就是this的该用与不该用,下面在看个简单的例子:
    1. var setColor = {
    2.         init:function(obj){
    3.                 this.obj = obj;                //this指向setColor
    4.                 this.obj.onclick = this.color;
    5.         },
    6.         color:function(){
    7.                 this.style.backgroundColor = '#000';        //this指向obj
    8.         }
    9. }
    复制代码

    就在一个类里,this却指向2处地方,有时这样总会让人觉得困惑.刚学习的人更会被this弄的晕头转向.而稍稍改变一下写代码的方式:
    1. var setColor = {
    2.         init:function(obj){
    3.                 setColor.obj = obj;                
    4.                 setColor.obj.onclick = setColor.color;
    5.         },
    6.         color:function(){
    7.                 this.style.backgroundColor = '#000';        //this可以方便方法的重用
    8.         }
    9. }
    复制代码

    这样一下来,代码可以更加的清晰了.所以编写代码的时候应该考虑好究竟今后的用途,还有能否重用.如果明确了不进行继承或是重用,个人觉得应该尽可能的避免使用this,更有个比较常出现的问题.如下:
    1. var Person = function(){
    2.         this.name = null;
    3. }
    4. Person.prototype.setName = function(name){
    5.         this.name = name;
    6. }
    7. Person.setName('tom');        //错误方式此时setName方法中的this将指向Person.prototypel,Person并没有setName方法
    复制代码

    前面讲过,若果不写成var p = new Person();p.setName('tom');该类里的this将会直接指向Person.prototypel.这种错误在编译时,还是运行时都不会报错.有时会造成让人很头痛的问题.所以在编写代码时,我总是很慎重的选用this.

    2.类的封装
    在Java里,对类的方法或是属性,可以设置为私有,这样就可以避免外部的调用,而JavaScript却不存在这样的设置,看看下面的代码:
    1. var person = {
    2.         name:null,
    3.         init:function(name){
    4.                 this.setName(name);
    5.         },
    6.         setName:function(name){
    7.                 this.name = name;
    8.                 return this.name;
    9.         }
    10. }
    11. person.init('tom');        //tom
    复制代码

    在这个类里,一共有2个方法,分别是init和setName,而我们只希望从init中运行setName,或是以后将会为里面添加的各种方法,而不希望出现:
    1. person.setName('tom');        //tom
    复制代码

    直接调用setName方法,正确的说,希望setName方法私有,还有name属性私有.避免别的程序员使用你的类时,调用了不想被调用的方法.
    那应该怎么对类的封装好呢?试试另一种编程方式吧,看看改版的怎么样:
    1. var person = function(){
    2.         var name = null;
    3.         var setName = function(n){
    4.                 name = n;
    5.                 return name;
    6.         }
    7.         return{
    8.                 init:function(n){
    9.                         setName(n);
    10.                 }
    11.         }
    12. }
    复制代码

    这样子,就可以讲原本要私有化的方法和属性私有化了,外部无法直接调用了.这也是利用了闭包而达成所需要的方式的.可是这种编程方式不易于读,尤其是新手看到这种代码会很吃力,还有在占用内存方面也要比一般的高些.
    好了,暂时先介绍到这里,下次有时间在说说闭包与作用域.
  • 相关阅读:
    搭建ARL资产安全灯塔
    免杀技术发展史
    米酷CMS 7.0.4代码审计
    腾讯安全实习 应用运维安全面试
    Docker部署CTF综合性靶场,定时刷新环境
    西湖论剑2020MISC-Yusa_yyds
    (转)马云炮轰银行监管的解读
    ATT&CK 实战
    Docker环境复现利用Redis未授权访问漏洞 >> 批量扫描检测利用
    修改CH340芯片信息
  • 原文地址:https://www.cnblogs.com/taoze/p/2424018.html
Copyright © 2011-2022 走看看