JavaScript语言知识收藏

 接触Web开发也早已有一段时间了,对javascript的认识也比此前有了一发入木三分的认识了,所以觉得应该整理一下。

 

一、JavaScript不帮助函数(方法)的重载,用一个事例阐明如下: 
function add(number) 

    alert(‘hello’); 

function add(number1, number2) 

    alert(‘world’); 

这时调用add(1),会弹出’world’,而不是’hello’,由此现象讲明写在文档前边的方法会覆盖掉前面的办法,所以有一个本身认为暂时是天经地义的尺度,就是假设情势名相同,则未来面对方法为主。 

二、JavaScript中函数(方法)就是一个目标,这里就不解释了,看一个例子比较直观 
function add(number) 

    alert(‘hello’); 

是等价于下边这种写法的 
var add = new Function(“number”,”alert(‘hello’)”); 
以此类推 
function add(number1, number2) 

    alert(‘world’); 

等价于 
var add = new Function(“number1″,”number2″,”alert(‘world’)”); 
此间一和二都是一致的,只是写法不同,底层是一致的,所以可以把JavaScript的不辅助重载的情景遵照面向对象的概念来精晓:首先add对象指向第一个Function对象,而后引用的对象改变了,指向了第二个新的Function对象了。示意图如下

 

ECMAScript 1

 

 

 所以可以得出一个这么的定论:JavaScript中的每个函数function都是new出来的Function对象。 
   
三、假诺在调用某个JavaScript函数的时候,没有给函数中的参数传值,则参数为undefined,例子如下: 
function add(number) 

    alert(number); 
    alert(number + 30); 

当在触发处调用add()的时候,显明尚无传到参数值,此时先弹出undefined(未定义), 
接下来弹出NaN(不是一个数Not A Number) 

四、arguments是每个函数的停放对象,应用那一个放手对象可以效仿面向对象的重载功效,例如 
function sum() 

    if(1 == arguments.length) 
    { 
        alert(arguments[0]); 
    } 
    else if(2 == arguments.length) 
    { 
        alert(arguments[0] + arguments[1]); 
    } 
    else if(3 == arguments.length) 
    { 
        alert(arguments[0] + arguments[1] + arguments[2]); 
    } 

调用如下: 
sum(1);    =>    1 
sum(1, 2);    =>    3 
sum(1, 2, 3);    =>    6 

五、由地点的事例又足以博得,JavaScript的函数就是Function的靶子,函数都有一个length属性,表示函数接收参数的个数。讲明如下: 
function add() {…..} 
function minus(num) {….} 
function multiply(num1, num2) {…..} 
调用如下: 
alert(add.length)    =>    0 
alert(minus.length)    =>    1 
alert(multiply.length)    =>    2 

六、JavaScript中有五种原始值,可以知晓为原生数据类型(这里仅仅是值JavaScript的,不同于3GL语言),它们分别是:Undifined,Null,Boolean,Number,String 
(1)Undefined数据类型的值只有一个:undefined,那里要小心一点就是,对于JavaScript中的变量,假诺只表明,而尚未赋值,则该变量的值为undefined。 
比如说:var s;    alert(s);   此时弹出的是undefined 

(2)Null数据类型的值只有一个:null 

(3)Boolean数据类型的值有四个:true和false 

(4)任何整数或者浮点数都是Number数据类型中的值,此外typeof(..)函数会回去参数的花色名称,例如: 
var s;   alert(typeof(s));     弹出undefined 
var a = 1;    alert(typeof(a));    弹出number 
var b = ‘hello’;    alert(typeof(b));    弹出string    
双引号表示原始类型在栈里 
而var c = new
String(“hello”);    alert(typeof(c));    弹出object,是在堆中的对象了 

(5)一个函数如若不重返值,则赶回’undefined’,typeof(..)重回的值是字符串类型的,注脚如下: 
function aa() {..//里面没有return出值..}         alert(aa());
会弹出undefined 

function bb() {….;  
return;  }      alert(bb);会弹出bb函数体{}中的所有源代码内容 

(6)使用没有注解,并且没有赋值的变量会报错,例如, 
var s;    alert(s2);  因为s2没有注解也未曾赋值,所以会报错 
alert(typeof(s));  弹出undefined 
alert(typeof(s2));  固然s2没有注解也从不赋值,但会弹出undefined 

因而可以综合出,typeof(..)的再次回到值有五个:undefined,boolean,number,string,object; 

(7)null与undefined的涉嫌:undefined实际上是从null派生而来的,讲明如下, 
alert(undefined == null);    会弹出true 

(8)在函数体内加不加var的界别:要是在函数体的内部,变量不加var,则默认该变量为全局变量,讲明如下: 
function test() 

    var s = ‘hello’; 

test(); 
alert(typeof(s));此时会重回undefined 
然而 
function test() 

    s = ‘hello’; 

test(); 
alert(typeof(s));会弹出string 
alert(s);会弹出hello 
因此可知,对此函数定义中的变量来说,加var表示局部变量,不加var表示全局变量。 

(9)强制类型转换有两种:Boolean(value),Number(value),String(value)
[这边可以作为函数] 
例如, 
var s = Boolean(null);    alert(s); 会弹出false 
var s = Boolean(“”);     alert(s);会弹出false 
var s = Boolean(“a”);   alert(s);会弹出true 
new Boolean(),new String(“…”),new Number(“…”)都是object类型的 

(10)在JavaScript中,Object是所有类的父类,类似于高级语言java 
var s = new Object(); 
alert(s);    弹出[object Object] 
alert(typeof(s)); 弹出object 
alert(s.propertyIsEnumerable(“prototype”));弹出false,这里是判断s中的属性是否可以枚举出来 

遍历window对象中的所有属性 
for(var temp in window) 

    alert(temp); 

delete操作和JavaScript中的晚绑定: 
var o = new Object(); 
o.name = “scott”; 
alert(o.name);   //会弹出scott 
delete(o.name); //删除晚绑定的name属性 
alert(o.name); //会弹出undefined 

七、JavaScript的面向对象的特征: 
(1)JavaScript是基于ECMAScript的,构造对象时可以从来用名字,例如 
var object = new Object;       <=>        var object = new
Object(); 
var s = new String;            <=>         var s = new
String(); 
var date = new Date;         <=>        var date = new Date(); 
即便如此,仍然提议加上括号,增添可读性!!!! 

(2)JavaScript中的数组,长度可以动态的充实,类似于java中的ArrayList,例如 
var array = new Array();        <=>      var array = [ ]; 
array.push(1); 
array.push(2); 
array.push(3); 
alert(array.length); //弹出3 
此间也足以用var array = [1,2,3];    alert(array.length); //弹出3 

(3)数组对象有一个办法sort(),可以对数组举办升序排序,例如 
var array = [3,2,1]; 
array.sort(); 
alert(array); //弹出[1,2,3] 
咋一看,很爽,但是 
var array = [1,3,21]; 
array.sort(); 
alert(array); //弹出[1,21,3] 
案由就在于:sort()方法对数组举行排序的时候,首先将数组中的每一个要素都转发为字符串,即调用每个元素的toString()方法,然后用字符串的ASCII码举办相比较!
所以’21’ < ‘3’很健康! 
此外,sort()可以接受一个排序的函数作为参数,依据参数排序,类似于java中的compare()方法 
例如, 
function compare(num1, num2) 

    var temp1 = parseInt(num1); 
    var temp2 = parseInt(num2); 
    return temp1 – temp2; 

var array = [3,1,21]; 
array.sort(compare); 
alert(array);  //弹出[1,3,21] 
这边仍是可以够用匿名函数的方法,类似于java中的匿名类 
array.sort(function(num1, num2) { 
    var temp1 = parseInt(num1); 
    var temp2 = parseInt(num2); 
    return temp1 – temp2; 
}); 

(4)对象的性能形式:[1]早绑定 [2]玩绑定
所谓早绑定,就是在对象生成在此以前绑定好的属性,例如,
var object = new Object();
object.name = “scott”;
alert(object.name);

所谓晚绑定,就是对生成好的对象扩展或收缩它的属性,例如,
object.hello = function() { alert(‘welcome’); }
object.hello();  //此时会调用object的hello方法,弹出welcome
delete object.hello();  //删除方法
object.sayName = function() { alert(this.name);
}  //这里this指的是object对象,类似于java一样
object.sayName();  //此时会弹出scott
object.sayName = function(name) {   //绑定一个传参数的点子
    this.name = name;
    alert(this.name);
}
object.sayHello(‘tiger’);   //此时弹出tiger

 

=================================================================

一、用工厂模式定义对象(类),这里是参照java的设计形式的工厂形式写的,例子如下

function createObject()
{
    var object = new
Object();  //这里请加上var,因为是方法体内部的有些变量
    object.username = “scott”;
    object.password = “tiger”;

    object.get = function()
    {
        alert(“username: ” + this.username + “/npassword: ” +
password);
    }
    return object;
}
调用如下,
var o = createObject();
o.get();  //此时会弹出username: scott
          //         password: tiger
该措施的好处是凡是学要对象了,不需要团结new一个出来,直接能够通过createObject生成对象,具体的底细都被打包起来了~  

 

 

上边的厂子格局即使有长处,然而变化的靶子属性都被默认写死成scott和tiger了,所以可以改善成如下带参数的工厂方法,例子如下,
function createObject(username, password)
{
    var object = new Object();
    object.username = username;
    object.password = password;

    object.get = function()
ECMAScript,    {
        alert(“username: ” + this.username + “/npassword: ” +
password);
    }
    return object;
}
调用如下,
var o = createObject(“scott”,”tiger”);
o.get();
该方法的好处比起一楼的点子,就是更灵敏的支配了要扭转的目的。

 

 

 

然而对于以上两种工厂方式,方法get()定义在createObject()函数的内部,从性能上考虑,没创建一个对象,就要生成一个get的function对象,但是在高级语言java中所有的对象都共同的用同一个方法,需要注意到是在JavaScript中get方法不是如此,工厂每次生成对象的时候,都会为get再生成一次相同的对象,比较消耗内存,因此,可以将get方法的定义放在createObject之外。例如,

function get()
{
    alert("username: " + this.username + "/npassword: " + this.password);
}

function createObject()
{
    var object = new Object();
    object.username = "scott";
    object.password = "tiger";
    object.get = get;
    return object;
}
调用方法一样的,有点就是优化了性能,功能还是一样~

 

 

 

二、构造函数的法门
function Person()
{
    this.username = “scott”;
    this.password = “tiger”;
    this.get = function()
    {
        alert(“username: ” + this.username + “/npassword: ” +
this.password);
    }
}
用那种情势定义相比较直观,与Java中变化对象很相近了,调用如下,
var person = new Person();
person.get();

诠释:当调用new
Person()的时候,执行流程跳到了函数中去了,在实施第一行代码以前,会转移一个目的,而this则会指向该目的,即便没有return该对象,不过此构造函数隐式地将目的return出去了;

此外,传递参数也是相近的,内部函数的定义也可以立异从而降低对内存的消耗,将它得到构造函数外面单独定义,所以可以改写成如下,
function get()
{
    alert(“username: ” + this.username + “/npassword: ” +
this.password);
}

function Person(username, password)
{
    this.username = username;
    this.password = password;
    this.get = get;
}

 

 

上述这种办法仍然不够直观,有另一种缓解方案如下, 

原型情势开创类:prototype 
function Person(){ } 
Person.prototype.username = “scott”; 
Person.prototype.password = “tiger”; 
Person.prototype.get = function() 
{ alert(“username: ” + this.username + “/npassword: ” + this.password);

调用方法: 
var p = new Person(); 
p.get(); 

只是此地运用prototype方法生成对象,不可能成立的时候先河化值,必须等对象成立出来之后,对性能修改。 
var person1 = new Person(); 
var person2 = new Person(); 
person1.username = ‘hello’; 
person1.get();   //hello tiger 
person2.get();   //scott tiger

ECMAScript 2 

 

 JavaScript中的字符串也是不可变的,与java机制中千篇一律,属于final类型的,字符串的拼接一会生成新对象

一旦Person.prototype.username = new Array();
//如下边一楼贴出的图样person1和person2会共享scott
    person1.username.push(“scott”);
    person1.get(); //scott
    person2.get(); //scott

 

 ECMAScript 3

 

 

 混合的构造函数与原型模式,属性接纳构造函数的艺术定义,方法应用原型格局定义(这里相比较推荐这种方法)
可以避免下面的共享属性的弊端,例如,
function Person(username,password)
{
    this.username = username;  //这里倘若this.username = new Array();
则新目的不会共享username
    this.password = password;
}
Person.prototype.get = function()
{
    alert(“username: ” + this.username + “/npassword: ” +
this.password);
}
调用方法:
var p = new Person(“scott”,”tiger”);
p.get();

 

 

 

 

另外还有一种方式:动态的原型方式
function Person()
{
    this.username = "scott";
    this.password = "tiger";
    if(typeof Person.flag == "undefined")  //或者Person.flag == undefined
    {
        Person.prototype.get = function()
        {
            alert("username: " + this.username + "/npassword: " + this.password);
        }
        Person.flag = true;
    }
}

 

 

 

 

下面来看看用JavaScript模拟java的继承特性
(1)继承的第一种方式:对象冒充
function Parent(username)
{
    this.username = username;
    this.hello = function()
    { alert("username: " + this.username); }
}

function Child(username,password)
{
    this.method = Parent;
    this.method(username);
    delete this.method;
    this.password = password;
    this.world = function()
    { alert("password: " + this.password); }
}

 

 

 

 ECMAScript 4

 

 

 依照上图,和带下划线的代码段,method属性作为桥梁引用Parent对象,调用Parent的构造函数后,删除了该属性!!
注意即使吧带下划线的代码段替换为Parent(username);是卓殊的,因为这样的话Parent中的hello()方法不可以继续下来~

 

 调用地点的继续
var parent = new Parent(‘father’);
var child = new Child(‘son’,’scott’);

parent.hello(); //father
child.hello();  //son
child.world();  //scott

有鉴于此继承机制真正实现了!!!!

 

(2)继承的第两种艺术:call()方法
此处先介绍call()方法:每个function,即Function对象都有call()那个模式,call(param1,param2,…),
param1表示调用call()方法的函数内部的this,param2,…对应调用call()方法的函数中的参数列表,例如,

function test(str)
{
    alert(this.name + ” ” + str);
}
var obj = new Object();
obj.name = ‘scott’;
test.call(obj,’tiger’); //这里将obj对象赋给test中的this,弹出scott
tiger

打探了call()的功用将来,我们来用call()实现持续机制,例子如下:

function Parent(username)
{
    this.username = username;
    this.hello = function()
    {
        alert(this.username);
    }
}

function Child(username, password)
{
    Parent.call(this,username);
    this.password = password;
    this.world = function()
    { alert(this.password); }
}

调用方法类似,这里就简单了。。。

 

(3)继承的第两种方法:apply()情势
这边相比一下apply()和call()
call(parm1,parm2,…,parmN)  五个参数

apply(parm1,new Array())  <=>
apply(parm1,[parm2,…,parmN])  六个参数

综上所述一下,apply方法的首先个参数和call一样,第二个参数是call前面参数组成的一个数组

下面用apply()来兑现连续的建制,如下:
function Parent(username)
{
    this.username = username;
    this.hello = function()
    { alert(this.username); }
}

function Child(username,password)
{
    Parent.apply(this,new
Array(username));  //等价于Parent.apply(this,[username]);
    this.password = password;
    this.world = function()
    { alert(this.password); }
}

 

 

(4)继承的第四种方式:原型链方式
function Parent() { }
Parent.prototype.hello = "hello";
Parent.prototype.sayHello = function()
{ alert(this.hello); }

function Child() { }
Child.prototype = new Parent();
Child.prototype = "world";
child.prototype.sayWorld = function()
{
    alert(this.world);
}

调用一下:
var child = new Child();
child.sayHello();  //hello
child.sayWorld();  //world

 

 

 

(5)继承的第五种方式:混合方式(最佳实践,推荐使用)

function Parent(hello)
{
    this.hello = hello;
}

Parent.prototype.sayHello = function()
{ alert(this.hello); }

function Child(hello,world)
{
    Parent.call(this,hello);
    this.world = world;
}

Child.prototype = new Parent();
Child.prototype.sayWorld = function()
{ alert(this.world); }

调用一下:
var child = new Child(‘hello’,’world’);
child.sayHello();  //hello
child.sayWorld();  //world

 

 

终极举个例证来接纳JavaScript的接轨机制的使用

function Shape(edge) //一个抽象的形状
{
    this.edge = edge;
}

Shape.prototype.getArea = function()//获取形状的面积,类似于接口中的方法,这里先回到-1
{ return -1; }

Shape.prototype.getEdge = function() //重临形状的边有多少条
{ return this.edge; }

上边定义子类,三角形
function Triangle(bottom,height) //三角形,出入参数为底边和高
{
    Shape.call(this,3);
    this.bottom = bottom;
    this.height = height;
}
Triangle.prototype = new Shape();
Triangle.prototype.getArea = function()//重临三角形的面积,覆盖父类的艺术
{ return 0.5 * this.bottom * this.height; }

调用三角形的对象和艺术:
var triangle = new Triangle(10,4);
alert(triangle.getEdge()); //3
alert(triangle.getArea()); //20

下边再定义一个四边形
function Rectangle(bottom, height)
{
    Shape.call(this,4);
    this.bottom = bottom;
    this.height = height;
}
Rectangle.prototype = new Shape();
Rectangle.prototype.getArea = function()
{ return this.bottom * this.height; }

调用四边形的目的和章程
var rectangle = new Rectangle(10,20);
alert(rectangle.getEdge());  //4
alert(rectangle.getArea());  //200