javascript的面向对象思想文化要

获取数据类型 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到20各小数的数字,超出这界定之值会引发错误。
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引入了另一个java运算符instanceof来缓解者问题。
var pp=new String(“hello world”);
alert(pp instanceof String);//true

ECMAScript最多无克超越25只参数

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”);

4回函数的函数;

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

解说:只有以函数的返回值是一个对象是才会产生,而当我们策划返回的是一个非对象类型时,该构造器将会照常回到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:移出最后一个因素,返回的是叫转换有底元素.
    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:会改目标元素,前2独参数,用于截取数组的片,尾部参数与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的频率高多;
很纠结的下结论:每个对象都发出一个构造器,而原型本身吗是一个目标,这当在它们要发一个构造器,而此构造器又见面生友好之原型,
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…..原型蝉联
    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….止持续和原型.处于效率的考虑,我们该尽可能的以部分只是选用的性质与办法上加至原型中去.如果形成了一个吓习惯,我们才指原型就是可知就后续关系的构建了.由于原型中之所有代码都是只是选用的,这表示后续自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