2014.01.26 笔记 (Javascript基础回顾之:类型)

 本文所包括的内容:

基本类型

  Javascript有5种基本数据类型(也叫简单数据类型):Undefined、Null、Boolean、Number、String 和1种复杂数据类型Object。

var undefinedVariable;
var nullValue = null;
var cnblogs = new Object();
var func = function () { };

typeof ("string"); 
typeof (100);
typeof (true);
typeof (undefinedVariable);
typeof (cnblogs);
typeof (undeclaredValue);
typeof (nullValue);
typeof (null)
typeof (func)

   告诉我结果是什么?

  

 

  

  • 好玩之一: 声明但未赋值 和 未声明的变量都是 undefined
  • 好玩之二: 只有声明并赋值为null,它的值才会null
  • 好玩之三: typeof(Object) 竟然是一个function
  • 好玩之四: typeof(Null) 竟然是一个object 

  Null 和Undefined这两种类型都只有一个值,即null和undefined。从逻辑上看null值表示一个空对象的指针,这就是为什么typeof(null)会返回Object。 并且undefined是派生自null值的,所以......

  • 好玩之五: null == undefined 是成立的。  

  但是想一想,Null和Undefined毕竟是两种不同的类型,即使他们是父类和子类的关系,在C#里面父类和子类也不能相等啊,不是么?其实null == undefined就是硬性规定,ECMA规定它们做相等性测试的时候要返回true所以他们返回true了。就好像我们在C#里面重写了equlas 方法一样。

  至于为什么 typeof(Object) 返回 function,请看下面的Object与object。

Object 与 object

  Javascript高级程序一书中说到 ”函数在ECMAScript中是对象,不是一种数据类型”。 好像是译者加上去的,既然typeof(Object) 都返回 function了,为什么还说function不是一种数据类型呢?Object 和 function之间是什么关系呢?

  在我看来,Object其实就是一个function,或者我们说Object是一个函数的名字比较容易理解,官方名称是构造函数。

var p = new Object();
p.name = "jesse";
p.age = 18;

function Person(name,age)
{
    this.name = name;
    this.age = age;
}

var p2 = new Person("jesse", 18);

  在上面的代码中, 如果我们把Object当作一个函数名那么 new Object() 和 new Person() 性质就是一样的了。通过 new 操作符得到一个 function 实例, 这里面的function就已经是类的概念了。所以这里的Object其实是一个function。这样我们就可以解释为什么typeof(Object)是function了。

  那我们在上面所说的复杂类型Object,它又是什么呢? 

  

  Object是function,但是 new Object() 则是 object。到这里面就搞清楚了首字母大写的这个Object是一个function,而首字母小写的这个object它才是一种数据类型。所以我建议大家以后说到类型的时候全部用小写,我们的基本类型是 string, number, boolean。大写的String, Number, Boolean 它们只是一个函数而已。而调用这些函数所得到的结果是,没错,是object。

  

  最后,我们是找不到Undefined 和Null 这两个函数的,所以这两种数据类型就是undefined和null(为什么typeof(null)会得到object已经说了)

  

  • 好玩之六: Object 不是object类型

基本包装类型

  我们上面讲了string, number, boolean是基本类型,基本类型和复杂类型最大的区别就是基本类型没有prototype属性。也就意味着你不能给基本类型随意的添加方法或属性。

var str = "str"; // typeof(str): string
var strObj = new String("str"); // typeof(strObj):object

strObj.name = "strObj";
strObj.alert = function () {
    alert(this.name);
};
strObj.alert();  // strObj

str.name = "str";  //wrong...
str.alert = function () {
    alert(this);
}
str.alert();  // this is wrong....  nothing is gonna happen.

  同时我们还说到了首字母大写的这个String是一个function,所以new String("str")得到的是一个object而不是一个string,这里大家要搞清楚了。我们的问题来了,为什么基本类型string会有一些初始的方法呢?它不是基本类型么?方法是怎么加上去的?

str = str.concat("str2");
strObj = strObj.concat("str2");  
strObj.alert();  //之后返回 string 不再是一个对象了, 所以这里也不再有alert方法了。

  str是string类型的变量,记住它不是一个对象。它是不应该有方法的,那么它的contact方法从何而来呢?这里后台在调用str.contact的时候实际上偷偷的完成了几步操作:

  1. 基于str创建一个String类型的实例
  2. 在实例上调用指定的方法
  3. 销毁这个实例

  将这三个步骤想象成这样:

var str2 = new String(str);
str = str2.concat("str2");
str2= null;

   我们可以把String,Number,Boolean叫做封装类型, 他们就好像我们在C#里面的自定义类型一样。 但是不要忘记了我们真正的基本类型是string, number, boolean。用String所构造出来的对象是属于object类型的。

  • 好玩之七: String 不是 string

值类型和引用类型

  我们上面讲到了5种基本类型:string, number, boolean, null, undefined 全部是值类型。Javascript中只有一种引用类型,也就是我们的复杂类型object。那么有人可能会好奇,那么像Date, Regex, Arrary这些是什么类型呢 ? 其实这里面的概念有一点混淆,如果你很好的理解了上面的Object 和object之间的区别,可能会比较好理解一点。 我们可以把function 看成是C#里面 class关键字,我们可以用class定义类,同样我们可以在Javascript中用function来定义类。

在C#中定义类:

 1 namespace ConsoleApplication1
 2 {
 3 class Person
 4 {
 5     public string Name { get; set; }
 6  
 7     public int Age { get; set; }
 8 }
 9  
10 class Program
11 {
12     static void Main(string[] args)
13     {
14         var p =new Person();
15         Console.WriteLine(p.GetType());  // ConsoleApplication1.Person
16  
17         Console.ReadLine();
18     }
19 }
20 }

 

  在Javascript定义类:

function Person(name,age)
{
    this.name = name;
    this.age = age;
}

var p = new Person();
typeof(p);   //object 

 

  你发现区别了么?如果我们在Javascript中用function定义类,他们的实例将永远是object, 包括原生的那些Date, Array, RegExp。

typeof (new Date());  // object
typeof (new Array()); // object
typeof (new RegExp()); // object

  • 好玩之八: 全部都是object

  如果全部都是object的话,那我怎么能知道这个对象到底是不是Date或者Person的实例呢?借助于instanceof 就可以了。

  

  •  终级好玩:我用function创建了一个Person类,然后用new得到一个Person的实例,结果它却不是Person类型的。 这就好像生了个孩子,供他吃穿,但是他却不跟你姓,这得有多么无私伟大才干得出来的事啊!

function类型

  function类型有两种,函数声明和函数表达式。函数声明具有优先级,可以在声明之前被使用,表达式却不能。

sayGoodNight(); // right
sayHello(); // wrong

var sayHello = function (name) {
    alert("Hello, " + name);
};

function sayGoodNight(Name) {
    alert("Good Night, "+ name);
}

  除此之外,函数表达式还可以像object一样,随意的添加属性。

var sayHello = function (name) {
    alert("Hello, " + name);
};

sayHello.age = 18;
sayHello.sayAge = function () {
    alert("I am" + 18) ;
}
sayHello.sayAge();  // I am 18

  但是,函数表达式到底是个什么玩意儿呢? 不能实例化,但是可以随意的添加属性,它和object有什么区别?我们在上面说过,object其实就是一个对象实例。

我们还有大写的Function, 它和function之间的关系会不会和String 和string 一样?( 以下内容比较费脑力,慎入!)

var sayHello = new Function(‘name‘,‘alert("My name is " + name  );‘);
sayHello(‘Jesse‘);
sayHello instanceof Function; // true

var sayHello2 = function (name) {
    alert(‘My name is‘ + name);
};
sayHello2 instanceof Function; // true

  我们上面调用Function去构造了一个函数。既没有用函数声明,也没有用函数表达式,不管怎么说这是第三种创建函数的方法,虽然肯定没有多少人用它,因为它不管是参数,还是函数体全部都是字符串,这写起来还不让人崩溃么?

  

  

  看出什么猫腻来了么?所谓的函数表达式,其实是用一个变量接收了一个function的对象而已。而这个function的对象则是Function的实例。包括用函数声明写出来的函数也是Function的实例。

function sayHello3(name)
{ 
    alert(‘My name is‘ + name);
}
sayHello3 instanceof Function;  // true

  但是,等等,我们前面说到的String, Date, Array都是function类型的,那Function也是么?

  

  我们前面说所有function的实例都是object类型的,但是对于Function 这个奇异的function来说,它的实例仍然是function类型的,并且我们可以用Function的实例再创造实例。原来我们所说的用function创造出来的类,它不是类,而是Function的实例。

function Person(name) {
    this.name = name;
}
Person instanceof Function; // true

  我们再结合自执行函数理解一下,也许会好一点:

(function () {
    alert("something...");
}());

  实际上我们上面的function(){} 会返回给我们一个function的实例,那么我们当然可以直接执行它了。这么看来function应该是Javascript里面最特别的类型了。

  • 好玩之十:所有的function都是Function的实例
  • 好玩之十一:Function 本身也是一个function

  

 最后我们来总结一下:

  • Javascript中有5种基本类型:string, number, boolean, null, undefined。
  • 另外一种复杂类型object 其实是function的实例。
  • 除了Function这个系统里面的function构造器以外,其它所有function的实例都是object类型的。
  • Date, Array, RegExp 这些都是function类型,同时也是Function的实例。同理,它们的实例也是object类型的。

 

  此文转自:Jesse Liu  

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。