ECMAScriptjavascript的面向对象思想文化要点

获取数据类型 typeof
undefined:访问有些不设有的或未经赋值的变量时就会得到一个undefined,用typeof 获取项目,获得的也是undefined;
null:它不可能由此javascript的源于动赋值,只好通过代码来形成;
var i=1+undefined;i=NaN;
var i=1+null;i=1;

1*undefined=NaN;
1*null=0;

number 的多少个处理数值的方法:
toFixed();再次来到的是钦命小数的数字的字符串,具身体表面示具有0到十九人小数的数字,超出那几个界定的值会引发错误。
var num=new Number(99);
alert(num.toFixed(2));//99.00;
toExponential()钦点要出口的小数的位数,结果是科学计数法。
var num=new Number(99);
alert(num.toExponential(1));//9.9e+1
toPrecision();用贰个参数表示数字的总和,不包涵指数。
var num=new Number(99);
alert(num.toPrecision(1))//1e+2,执行了舍入操作
alert(num.toPrecision(2))//99
alert(num.toPrecision(3))//99.0
alert(num.toPrecision(4))//99.00
toFixed()和toExponential()和toPrecision()方法都会经行舍入操作,以便用科学的小数位数正确的代表二个数。

typeof运算符再次回到引用类型的仓库储存值会见世贰个标题,无论引用的是什么样品种的对象,它都回来object。ECMAScript引入了另1个java运算符instanceof来缓解这么些难题。
var pp=new String(“hello world”);
alert(pp instanceof String);//true

ECMAScript最多不可能跨越2三个参数

array类
var a=[“yellor”,”green”];
var b=a.concat(“yellow”,”gray”);//将参数添加到a中,重回新的数组
alert(b.toString());
alert(a.toStrong())

/************************函数****************************/
1函数也是数额,本质上与其他变量并无区别
function gys(){alert(“gys”);}
var gys=function(){alert(“gys”)}
typeof gys=====>function
和变量一样,大家得以对它拷贝给差别的变,甚至删除;
var sum=function(a,b){return a+b;}
var add=sum;
delete sum;
typeof sum====>undefined
typeof add====>function
add(1,2)=======>3;

2:匿名函数、回调函数,把函数当做参数字传送递;
function gys(a,b){
return a()+b();
};
function one(){return 1;}function two(){return 2;}
gys(one,two);或者gys(function(){return 1;},function(){return 2})

将函数A传递给函数B,并由B来执行A,A就成了回调函数.
优势:1在不做命名的气象下传递函数,节省了全局变量;2,函数调用委托给另三个函数,节省代码的编纂;3天性更高,不必要到内部存款和储蓄器中找那一个变量;

3自调函数
  1:不带参数
(function(){alert(“gys”);})()
  2:带参数
(function(name){alert(name)})(“guoyansi”);

6回去函数的函数;

function A(){alert(“a”);
return function(){alert(“b”);}
}

var newfun=A();====>a;
newfun()====>b;

或A()();

5:重写自身:
   1  function a(){alert(“a”);
return function(){alert(“b”);}
}
a=a();
a();

   2
function a(){alert(“a”);a=function(){alert(“b”)}}
a();a();

/**************对象************************/
1..创设对象时,实际上赋予了这几个指标几本性质—构造器属性constructor,该属性实际上是一个针对性用于制造对象的构造器函数的引用;(函数名),
function Person(){this.name=”guoyansi”;}
var p=new Person();
alert(p.constructor);
alert(typeof p.constructor);====>function
var p1=new p.constructor();
alert(p1.name);

2…instanceof:内定对象是或不是由某些内定的组织器函数所创设的
function Person(){}
var p=new Person()
var obj={};
p instanceof Person====>true;
p instanceof Object====>true;
obj instanceof Object====>true;

3….回去对象的函数
 1 function Person(){this.name=”guoyansi”;}
var p=new Person();
p.name====>guoynsi;

 2 function Person(){this.name=”guoyuansi”; return {b:2};}
var p=new Person();
p.name====>undefined;
p.b======>2

表达:唯有在函数的重返值是一个对象是才会发生,而当大家策划重返的是1个非对象类型时,该构造器将会照常回到this.

4….指标的可比,引用相等时才能等于;
    var a={name:”gys”};var b={name:”guoyansi”};
a===b===>false;
a==b=====>false;

5….内建目的
   1.数码封装类对象:object,array,boolean,number,string
   2.工具类对象:math,date,regexp;
   3.错误类对象:

            /*******object*******/
object是javascript中全部的目的的父级对象,我们所创制的兼具目的都一而再于此;
var 0bj={};//对象文本标石法;
var obj=new Object();
            /****array*****/
var a=[];var a=new Array();
var a=new Array(1,2,”three”);//直接设定成分
var a=new
Array(3);//假如大家传递的是四个数字,该数字就被看成是五个数组的长度.
数组的尺寸会趁着成分的增多而充实,若是钦命了成分个数,并且数值高于当前数组中成分的个数,剩下的那部分会自动成立为undefined;
  数组的方法:
     push:会在数组的结尾添加多少个新因素,再次来到的是新数组的长度,
     pop:移出最终1个因素,重返的是被移出的成分.
    var a = [1, 2, 3];
        alert(a.push(“new”));
    sort:排序,
        var a = [“fd”,45,1,35,3,2];
            var b = a.sort();
             
 alert(b);====>[1,2,3,35,45,”fd”];//a,b的应用是相等的;

        var a = [100,45,1,35,3,2];
            var b = a.sort();
             
 alert(b);====>[100,1,2,3,35,45];//个人感觉不准,不建议使用
    join:将数组拆分成字符串,用相应的字符连接;
    var a=[1,2,3];
    a.join(“gys”)=====>1gys2gys3;
    slice在不修改数组的境况下,截取数组的中的有个别片段;
    var a = [45, 1, 35, 3, 2];
        var b = a.slice(1, 3);
        alert(b);====>[2,35]//包含1,不包含3,
  
 splice:会修改指标成分,前1个参数,用于截取数组的某些,尾部参数和slice不雷同,,前边的参数用来补偿被切除的部分.
     var a = [45, 1, 35, 3, 2];
        var b = a.splice(1, 3, “g”, “y”, “s”);
        alert(a);====>[45,”b”,”y”,”s”,2];
    alert(b);=====>[1,35,3];

        /*****Function**********/冷门知识,不做主要讲解;
function sum(a,b){return a+b;}
var sum=new Function(“a”,”b”.”return a+b”);
        /*********arguments***********/
function a(){return arguments;}
a(1,2,3);======>[1,2,3]//”类似”数组的对象,,没有sort等艺术,唯有索引和尺寸length;
arguments有二个callee属性,重临的是函数自个儿的引用;valueof再次回到”对象”的自笔者;
function a(){return arguments.callee;}
 (function (count) {
            if (count < 5) {
                alert(count);
                arguments.callee(count);
            }
        })(1)//无穷境的递归

/************************原型*************************************/
1…..运用原型添加方法和性质
    1.function Person(name){
    this.name=name;this.whatAreYou=function(a){return a
    }
    2.Prson.prototype.age=23;
    Person.prototype.study=function(a){return a;}
    3.Person.prorotype={age:23,study:function(){return this.age;}}
2….使用原型的措施和总体性
    var p=new Person(“guoyansi”);
    p.name=====>guoyansi;
    p.whatAreYou(“gys”)===>gys
    p.age===>23
    p.study()====>23
3….原型的驻留概念:由于在js中,对象都是透过传递引用情势来传递的,因而大家所开创的各类新对象的实业中并没有一份属于自个儿的原型副本.意味着,我们每时每刻能够修改原型,并且与之唇齿相依的靶子也都会继续这一改变.
    Person.prototype.get=funciton(what){return this[what];}
    p.get(name);====>guoyansi
  
 尽管p对象在get在此之前早已被成立了,然则get照旧能够访问p对象中的属性和方法;
4….做客自个儿性质和原型属性的法则;
    上例中的study使用this指针达成的,其实也得以用原型来访问.
stydy:funciton(){Person.prototype.age;}
  
 由哪些不一样么:当访问有个别属性时,先在友好的目的中遍历,借使遍历到了,就随即回到,假设没找到,脚本引擎就到开创当前指标的组织器函数的原型中走访(等价于Person.constructor.prototype),假若找到了
就及时回到该属性值;由此Person.prototype.name要不this.name的频率高很多;
很纠结的结论:每一种对象都有三个构造器,而原型本身也是2个对象,那以为着它必须有3个构造器,而以此构造器又会有自个儿的原型,
5…断定属性是源于原型依旧源于指标自小编;
hasOwnProperty:对象自作者性质,重临true,不然再次回到false,
propertyIsEnumerable:感觉和地点没什么分裂.
只顾:要是调用来自原型上的有个别对象,那么该目的中的属性是足以枚举的;
Person.prototype.propertyIsEnumerable(“get”)=====>true;
6….isPrototypeOf告诉大家当下指标是不是是另三个指标的原型;
var mokey = {};
        function Person(name) {
            this.name = name;
            this.whoAreYou=function(a){return a;}
        }
Person.prototype = mokey;
var p = new Person(“guoyansi”);
alert(mokey.isPrototypeOf(p));====>true

/****原型陷阱,不或许解释*****/
    function Dog() { }
        Dog.prototype.say = function () { alert(“say”); };
        var d = new Dog();
        alert(d.constructor);=====>Dog
        Dog.prototype = {};
        var dd = new Dog();
        alert(dd.constructor);======>指向了 Object,不可能解释

缓解的法门,
 function Dog() { }
        Dog.prototype.say = function () { alert(“say”); };
        var d = new Dog();
        alert(d.constructor);=====>Dog
        Dog.prototype = {};
        Dog.prototype.constructor = Dog;//添加此句话.
        var dd = new Dog();
        alert(dd.constructor);=====>Dog
小心:在重写prototype时,重置相应的constructou属性是1个好习惯;

/****************************继承***************************************/
1…..原型持续
    function Shape() {
            this.name = ‘shape’;
            this.toString = function () { return this.name; };
        }
        function TwoShape() {
            this.name = ‘2D shape’;
        }
        function Triangle(side, height) {
            this.name = ‘Triangle’;
            this.side = side;
            this.height = height;
            this.getArea = function () { return this.side * this.height
/ 2; }
        }
        TwoShape.prototype = new Shape();
        TwoShape.prototype.constructor=TwoShape;
        Triangle.prototype = new TwoShape();
        Triangle.prototype.constructor = new Triangle();
        var my = new Triangle(5, 10);
        alert(my.getArea());=====>25;
       
alert(my.toString());====>Triangle;,this始终是指向实体对象的,而不实施原型对象.因为
Shape的实体是位于Triangle的原型上,所以最后指向Triangle的实体.
探讨javascript引擎在调用my.toString()时都做了怎么着事;
   
 1.第二在my对象中遍历全数属性,没有找到,在到原型链中找toString()属性,就是到TwoShape创造的实体中寻觅,没找到,继续去原型中去找,同理原型被Shape的实业所掩盖,,就是到Shape中搜索这么些点子,最终找到了,立即重返.
    2.由此instanceof判断my是不是是上述七个构造器的实体;
    alert(my instanceof Shape);=====>true
        alert(my instanceof TwoShape);=====>true
        alert(my instanceof Triangle);=====>true
        alert(my instanceof Array);=====>false
    3.isPrototypeOf();判断当前指标是还是不是是另一个对象的原型;
    var a = Shape.prototype.isPrototypeOf(my);alert(a);===>true
        a = Shape.isPrototypeOf(my);alert(a);====>false
        a = TwoShape.prototype.isPrototypeOf(my);
alert(a);====>true
        a = TwoShape.isPrototypeOf(my); alert(a);====>false
        a = Triangle.prototype.isPrototypeOf(my);
alert(a);=====>true
        a = Triangle.isPrototypeOf(my);alert(a);=====>false;
2….将共享属性迁移到原型中去;
    function Shape(){this.name=’shape’;}//每当大家用new
Shape()新建对象时,各类实体都会有三个全兴的name属性,并在内部存款和储蓄器中有所和谐独立的贮存空间,那样会冒出一些成效低下的境况.
    function Shape(){}
Shape.prototype.name=’shape’;//将name属性添加到实体所共享的原型对象中去,那样的话,每当咱们在用new Shape()新建对象时,新指标就不在含有属于自个儿的name属性了,尽管那样做平凡会更有功效,但那也只是针对性对象实体中的不可变属性而言的,别的那种情势也一律适用于对象中的共享性方法.

    function Shape(){}
    Shape.prototype.name=”shape”;
    shape.prototype.toString=function(){return this.name;}
    
    function TwoDShape(){}
    function TwoDShape.prototype=new Shape();
    TwoDShape.prototype.constructor=TwoDShape;
    TwoDShape.prototype.name=’2D Shape’;
    
    function Triangle(side,height){this.side=side;this.height=height;}
    Triangle.prototype=new TwoDShape()
    Triangle.prototype.constructor=Triangle;
    Triangle.prototype.getArea=function(){return
this.side*this.height;}
    

3….只持续与原型.处于成效的考虑,大家应有尽只怕的将一些可选取的性质和艺术添加到原型中去.假如形成了1个好习惯,大家仅仅凭借原型就能完结后续关系的构建了.由于原型中的全体代码都以可选取的,那代表后续自shape.prototype比继承子new
shape()所开创的实业要好得多,毕竟,new
shape()方式会将shape的习性设定为对象自笔者性质,那样的代码是不足重用的,
    function Shape(){}
    Shape.prototype.toString=function(){return this.name;};
    function TwoDShape(){};
    TwoDShape.prototype=Shape.prototype;
    TwoDShape.prototype.constructor=TwoDShape;
    TwoDShape.prototype.name=’2D shape’;
    function Triangle(side,height){this.side=side;this.height=height;}
    Triangle.prototype=TwoShape.prototype;
    Triangle.prototype.constructor=Triangle;
    Triangle.prototype.name=’Triangle’;
    Triangle.prototype.getArea=function(){return
this.side*this.height;}//那里最根本的都以援引传递,不是值传递,而且步骤少了,速度更快;
浅析修改前寻找toString的手续:my实体==>my原型–>twoDShape实体==>TwoDShape原型–>shape实体==>shape原型==>找到toString();
修改后:my实体==>my原型–>TwoDShape原型–>shape原型==>找到toString();
题材:这种不难的拷贝原型从成效上的话纵然功用更高.由于子对象与父对象指向的是同二个对象,所以一旦子对象对其进展了改动,父对象也会跟着被更改,甚至具备的三番五次关系也是如此.
Triangle.prototype.name=’Triangle’;此时Shape.prototype.name的值也会趁着改变了.也正是说,当大家再用new
Shape()新建对象是,新对象的name也会是”Triangle”;
4…..临时协会器—–new F();打破那种相关关系;
    function Shape(){}
    Shape.prototype.name=’shape’;
    Shape.prototype.toString=function(){return this.name;};

    function TwoDShape(){}
    var F=function(){};
    F.prototype=Shape.prototype;
    TwoDShape.prototype=new F();
    TwoDShape.prototype.constructor=TwoDShape;
    TwoDShape.prototype.name=’2d shape’;
    function Triangle(side,height){this.side=side;this.height=height;}
    var F=function(){};
    F.prototype=TwoDShape.prototype;
    TwoDShape.prototype=new F();
    Triangle.prototype,constructor=Triangle;
    Triangle.prototype.name=”Triangle;
    Triangle.prototype.getArea=function(){return
this.side*this.height/2};
敲定:尽量将要共享的天性与艺术添加到原型中,然后围绕原型营造继承关系,相当于说,那种主张不鼓励对象的本身性质纳入继承关系,其背后的来源在于一旦目的自小编性质被设定得太过具体,会令其丧失可选拔性.

5…应用uber——子对象访问父对象的点子;
      function Shape(){}
    Shape.prototype.name=’shape’;
    Shape.prototype.toString = function () {
        var result = [];
        if (this.constructor.uber) {
            result[result.length] =
this.constructor.uber.toString();
        }
        result[result.length] = this.name;
        return result.join(‘, ‘);
    };

    function TwoDShape(){}
    var F=function(){};
    F.prototype=Shape.prototype;
    TwoDShape.prototype=new F();
    TwoDShape.prototype.constructor=TwoDShape;
    TwoDShape.uber=Shape.prototype;
    TwoDShape.prototype.name=’2d shape’;

    function Triangle(side,height){this.side=side;this.height=height;}
    var F=function(){};
    F.prototype=TwoDShape.prototype;
    Triangle.prototype = new F();
    Triangle.prototype.constructor=Triangle;
    Triangle.uber=TwoDShape.prototype;
    Triangle.prototype.name=’Triangle’;
    Triangle.prototype.getArea=function(){return
this.side*this.height/2};

    var my=new Triangle(5,10);
    alert(my.toString());====>shape, 2d shape, triangle;

6…..将继续部分封装成函数;
    var extend = function (Child, Parent) {
            var F = function () { };
            F.prototype = Parent.prototype;
            Child.prototype = new F();
            Child.prototype.constructor = Child;
            Child.uber = Parent.prototype;
        }
事例:extend(Triangle,Shape);或extend(Triangle,TwoDShape);而那也是YUI库在贯彻持续关系时所利用的方法YAHOO.lang.extend(Triangle,Shape)

7….属性拷贝,将父对象的性质全部正片到子对象的原型中去,
    function copyShunXing(Child,Parent){
    var p=Parent.prototype;
    var c=Child.prototype;
    for(var i in p){
        c[i]=p[i];
        }//此时只是完结了拷贝属性的行事,还不存在任何涉及;
    c.uber=p;
    }
那种办法只含有基本数据类型,全数的靶子类型(包蕴函数与数组)都以不足复制的,因为她俩只扶助引用传递;

相比较继承和性情拷贝;
    var Shape = function () { };
        var TwoDShape = function () { };
        Shape.prototype.name = ‘shape’;
        Shape.prototype.toString = function () { return this.name; };
        extend(TwoDShape, Shape);
        var td = new TwoDShape(TwoDShape, Shape);
        alert(td.name);===>shape
        alert(TwoDShape.prototype.name);===>shape

8…..小心处理引用拷贝,
    var A = function () { }, B = function () { };
        A.prototype.shuzu = [1, 2];
        A.prototype.name = ‘guoyansi’;
        copyShunXing(B, A);
        alert(B.prototype.hasOwnProperty(‘name’));=====>true;
        alert(B.prototype.shuzu === A.prototype.shuzu);====>true
        B.prototype.shuzu.push(4, 5, 6);
        alert(A.prototype.shuzu);=====>1,2,3,5,6;//引用拷贝
  
 假诺大家用其它三个目的(数组,json,function等)对其B的数组经行重写,事情就全盘不一样了..A的shuzu属性会继续引用原对象,而B的shuzu属性则指向了新的对象.

9…..目的之间的一连;
    function extendCopy(p) {//浅拷贝
            var c = {};
            for (var i in p) {
                c[i] = p[i];
            }
            c.uber = p;
            return c;
        }
        var shape = { name: ‘shape’,
            toString: function () {
                return this.name;
            }
        };
        var twoDee = extendCopy(shape);
        twoDee.name = ‘2d shape’;
        twoDee.toString = function () { return this.uber.toString() +
‘,’ + this.name; };
        var triangle = extendCopy(twoDee);
        triangle.name = ‘Triangle’;
        triangle.getArea = function () { return this.side * this.height
/ 2; };
        triangle.side = 5; triangle.height = 10;
        alert(triangle.getArea());====>25;
     alert(triangle.toString());====>shape,2d shape,triangle;

10….深拷贝
    后边的extendCopy是浅拷贝,现在来谈谈深拷贝;
由在此从前边的学习,大家知道了当对象的习性被拷贝是,实际上拷贝的只是该指标在内部存款和储蓄器中的地方指针.在那种情况下,我们修改了拷贝对象,就一律修改了原对象.而深拷贝则能够帮忙大家防止那方面包车型客车难点.深拷贝的兑现方式和浅拷贝的基本相同,也需求对遍历对象的性子实行拷贝操作.只是在碰着八个对象引用性的质量时,大家需求再一次对其调用深拷贝函数.
    function deepCopy(p, c) {
            var c = c || {};
            for (var i in p) {
                if (typeof p[i] === ‘object’) {
                    c[i] = (p[i].constructor === Array) ? [] :
{};
                    deepCopy(p[i], c[i]);
                }
                else
                    c[i] = p[i];
            }
            return c;
        }
        var parent = { number: [1, 2, 3], letters: [‘a’, ‘b’, ‘c’],
obj: { prop: 1 }, bool: true };
        var mydeep = deepCopy(parent);
        var myshallow = extendCopy(parent);
        mydeep.number.push(4, 5, 6);
        alert(mydeep.number);====>1,2,3,4,5,6
        alert(myshallow.number);======>1,2,3
        myshallow.number.push(10);
        alert(myshallow.number)====>1,2,3,10
在jQuery的较新本子中,继承关系的落到实处平日都会利用深拷贝的方式.
11.构造器的借用继承
     function Shape(id) {
            this.id = id;
        }
        Shape.prototype.name = ‘shape’;
        Shape.prototype.toString = function () { return this.name; };

        function Triangle() {
            Shape.apply(this, arguments);
        }
        Triangle.prototype.name = ‘TRiangle’;
        var t = new Triangle(101);
        alert(t.id);===>101;继承了构造器中的id属性
        alert(t.toString());====>[object
object];没有持续原型中的属性.
因为大家尚无调用new
Shape()创造任何四个实例,自然其原型也常有没有被调用.
构造器借用的一大优势:当大家创立三个一连于数组恐怕别的对象类型的子对象时,将获取三个戏耍全全的新值(不是三个引用),对它做其余修改都不会影响其父对象.
12…借出构造器和原型复制.
    function Shape(id) {
            this.id = id;
        }
        Shape.prototype.name = ‘shape’;
        Shape.prototype.toString = function () { return this.name; };

        function Triangle() {
            Shape.apply(this, arguments);
        }
        copyShunXing(Triangle,Shape);
        Triangle.prototype.name = ‘TRiangle’;
        var t = new Triangle(101);
        alert(t.id);====>101
        alert(t.toString());====>TRiangle