zoukankan      html  css  js  c++  java
  • JS 创建对象(常见的几种方法)

    今天看到javascript对象name : name,这样的表示方法,突然发现跟PHP的对象不一样,

    public、protected、private、    static、  const

    所以今天又学了一招.

    方便学习js类的朋友,让你快速的掌握js类的定义方法,方法有很多种,结果都一样。大家可以根据自己的爱好选用。

    贴个代码先:

    function O(user,pwd){ //use constructor
    this.user=user;
    this.pwd=pwd;
    this.get=get;
    return this;
    }
    function O2(user,pwd){ //use factory
    var obj=new Object();
    obj.user=user;
    obj.pwd=pwd;
    obj.get=get;
    return obj;
    }
    function O3(){ //use prototype
    }
    O3.prototype.user='abc';
    O3.prototype.pwd='dis';
    // O3.propotype.get='get';
    //O3.prototype.get(){
    //alert(this.pwd);
    //}
    function O4(user,pwd){
    this.user=user;
    this.pwd=pwd;
    return this;
    }
    O4.prototype.get=function(){alert('123');}
    
    //function get(){
    //alert("This User:"+this.user);
    // }
    function test2(){
    //var a=new O2('Us','Pw'); use factory & constructor
    //var a=new O3(); //use prototype
    //a.get();
    var a=new O4('*U4','P4'); //混合
    //a.user='Not ABC'; //set new property
    //alert(a.user);
    a.get();
    } 

    常用的MS 就这几种,可能还有其它的.碰到再说吧....
    题外话:昨天手欠,试图用alert(window.appName)到ff之下去 查看浏览器版本,结果弹出的竟然是Netscape,咋不是 firefox。继而又跑去chrome下试验,又一次弹出了Netscape。baidu搜 Netscape 竟然发现js就出自Netscape公司。惭愧啊惭愧!!!研究了这么久的js都不认识祖师爷。于是又跑去找了找族谱,原来js出自Brendan Eich之手,95年他创造js时候,也不过就31岁。哎呀,真是白活了,如他一般老的我,到现在都学不会js,真是人比人气死人。。js当初设计的时 候,没有想到自己能从一部打电话用的手机变成集拍照,上网,游戏,电话于一身的智能机。真是造化弄人!!!也许各中的神奇,连Brendan Eich本人都没有想到。应该说Brendan Eich创造了js,而一大批的js牛人成就了今天如此复杂的js。
    js不是木有类么?没关系,人家不是设计了原型属性么~
    js不是木有块级作用域么?没关系,人家不是有作用域链么~
    js怎样实现成员变量私有化?哦,用闭包解决吧~
    哦,这么多基本概念,彻底的晕掉了,路漫漫其修远兮。
    言归正传,本文讨论几种js创建对象的方法,先从最好理解的工厂模式开始:

    function createPerson(name,age,job){
    var o = {};
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
    alert(this.name);
    };
    return o;
    }
    var tanya = createPerson("tanya","30","female");
    var ansel = createPerson("ansel","30","male");
    tanya.sayName();
    ansel.sayName(); 

    这里先定义o为一个空的对象,然后为o设置了一堆属性。其实也可以直接给o属性的嘛,所以如果这样写也是ok的。

    function createPerson(name,age,job){
    var o = {
    name : name,
    age : age,
    job : job,
    sayName : function(){
    alert(this.name);
    }
    };
    return o;
    }
    var tanya = createPerson("tanya","30","female");
    var ansel = createPerson("ansel","30","male");
    tanya.sayName();
    ansel.sayName(); 

    还有一种办法是利用无敌的this,因为this就表示当前运行时的对象,将构造函数this的作用域指向新对象,将当前运行对象的属性和方法都赋给新对象,这样对象模式称为构造函数模式

    function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
    alert(this.name);
    };
    }
    var tanya = new Person("tanya","30","female");
    var ansel = new Person("ansel","30","male");
    tanya.sayName();
    ansel.sayName(); 

    在这个例子中,tanya和ansel都有一个constructor属性,该属性指向person。
    考虑一下如下的情况:

    function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
    alert(this.name);
    };
    }
    Person("tanya","30","female");
    Person("ansel","30","male");
    window.sayName();
    window.sayName(); 

    发现两次弹出的都是ansel,这是因为不用new的话,就不是一个person的实例,而仅仅在执行函数。而在全局作用域调用一个函数时this总是指向Global对象。而Global对象在浏览器中就是window对象。
    我们还可以用构造模式在另外一个对象中调用sayName方法,还记得Apply和call么,来吧再考虑另外一种情况:

    function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
    alert(this.name);
    };
    }
    var olivia = {};
    Person.call(olivia,"tanya","30","female");
    olivia.sayName();
    var philip = {}
    Person.apply(philip,["ansel","30","male"]);
    philip.sayName(); 

    原型模式就要考虑原型链了,分析一下,sayName方法在实例中被重复定义了两次,但其实没有必要创造两个一样的副本。使用原型方法,可以使是tanya和ansel的共享一个sayName方法。
    于是原型模式的写法如下:

    function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    }
    Person.prototype.sayName= function(){
    alert(this.name);
    };
    var tanya = new Person("tanya","30","female");
    var ansel = new Person("ansel","30","male");
    tanya.sayName();
    ansel.sayName(); 

    实际应用时,不是一成不变的套用某种模式,活学活用。需要共享方法的时候就用原型模式,需要使用副本的时候就用构造模式,还可以结合起来,把所有信息都封装在构造函数中,而通过在构造函数中初始化原型,使得对象保持了同时使用构造函数和原型的优点。

    function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    if (typeof sayName != "function" ){
        Person.prototype.sayName= function(){
        alert(this.name);
      };
      }
    }
    var tanya = new Person("tanya","30","female");
    var ansel = new Person("ansel","30","male");
    ansel.sayName = function () {
      alert("Hi ansel, how hansome you are!");
    }
    tanya.sayName();
    ansel.sayName(); 
  • 相关阅读:
    使用Angular CLI生成 Angular 5项目
    asp.net core 2.0 web api + Identity Server 4 + angular 5 可运行前后台源码
    依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构
    Git基本命令 -- 别名 + 忽略 + 推送
    Git基本命令 -- 历史
    多线程,论多核时代爱恨情仇
    凛冬将至,用几款特效暖暖身
    HTML5游戏开发引擎,初识CreateJS
    详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)
    详解设计模式六大原则
  • 原文地址:https://www.cnblogs.com/wicub/p/3477490.html
Copyright © 2011-2022 走看看