1、null
"null" means the object reference is invalid in .NET。
null关键字是表示不引用任何对象的空引用的文字值,是引用类型变量的默认值。那么也只有引用型的变量可以为NULL,如果 int num=null,的话,是不可以的,因为Int是值类型的。
Code
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest = null;
Console.WriteLine(strTest);
//int strLen = strTest.Length; //字符串长度,引用为空,异常
//Console.WriteLine(strLen);
//Console.WriteLine(strTest.ToString()); //引用为空,ToString()异常
//int num = null; //编译器直接提示 无法将Null转化为int
//Console.WriteLine(num);
Console.ReadLine();
}
}
}
2、string.Empty和""
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest = null;
Console.WriteLine(strTest);
//int strLen = strTest.Length; //字符串长度,引用为空,异常
//Console.WriteLine(strLen);
//Console.WriteLine(strTest.ToString()); //引用为空,ToString()异常
//int num = null; //编译器直接提示 无法将Null转化为int
//Console.WriteLine(num);
Console.ReadLine();
}
}
}
这个很好理解,string.Empty就是"",大多数情况下,二者可以互换。
Code
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest1 = "";
string strTest2 = string.Empty;
//输出两个字符串
Console.WriteLine(strTest1);
Console.WriteLine(strTest2);
//输出两个字符串的长度
int strLen1 = strTest1.Length;
int strLen2 = strTest2.Length;
Console.WriteLine(strLen1);
Console.WriteLine(strLen2);
//两个字符串ToString()
Console.WriteLine(strTest1.ToString());
Console.WriteLine(strTest2.ToString());
Console.ReadLine();
}
}
}
3、三者主要区别
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest1 = "";
string strTest2 = string.Empty;
//输出两个字符串
Console.WriteLine(strTest1);
Console.WriteLine(strTest2);
//输出两个字符串的长度
int strLen1 = strTest1.Length;
int strLen2 = strTest2.Length;
Console.WriteLine(strLen1);
Console.WriteLine(strLen2);
//两个字符串ToString()
Console.WriteLine(strTest1.ToString());
Console.WriteLine(strTest2.ToString());
Console.ReadLine();
}
}
}
(1)、string.Empty是在String类的静态构造函数中定义的.并且注意,由于CLR的string interning的作用(传说中的拘留池), string.Empty和""完全指向同一片内存区域,不会每次""都出现一个新的字符串引用(所以 线程lock空字符串的时候是会出大问题的).
Code
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest1 = "";
string strTest2 = string.Empty;
//两个字符串是否相等
Console.WriteLine(strTest1==strTest2);
Console.WriteLine(strTest1.CompareTo(strTest2));
Console.WriteLine(strTest1.Equals(strTest2));
Console.WriteLine(object.ReferenceEquals(strTest1,strTest2)); //两个引用不是指向同一个地址
string strTest3 = "";
string strTest4 = string.Empty;
Console.WriteLine(object.ReferenceEquals(strTest1, strTest3)); //两个引用指向同一个地址
Console.WriteLine(object.ReferenceEquals(strTest2, strTest4)); //两个引用指向同一个地址
Console.ReadLine();
}
}
}
(2)、三者的内存分配情况
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest1 = "";
string strTest2 = string.Empty;
//两个字符串是否相等
Console.WriteLine(strTest1==strTest2);
Console.WriteLine(strTest1.CompareTo(strTest2));
Console.WriteLine(strTest1.Equals(strTest2));
Console.WriteLine(object.ReferenceEquals(strTest1,strTest2)); //两个引用不是指向同一个地址
string strTest3 = "";
string strTest4 = string.Empty;
Console.WriteLine(object.ReferenceEquals(strTest1, strTest3)); //两个引用指向同一个地址
Console.WriteLine(object.ReferenceEquals(strTest2, strTest4)); //两个引用指向同一个地址
Console.ReadLine();
}
}
}
a、string strTest=null这样定义后,只是定义了一个string 类的引用,strTest并没有指向任何地方,在使用前如果不实例化的话将报错。
b、string strTest=string.Empty这样定义后,strTest是一个空字符串,空字符串是一个特殊的字符串,只不过这个字符串的值为空,在内存中是有准确的指向的。 string.Empty不分配存储空间
c、string strTest="","" 分配一个长度为空的存储空间
Code
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest1 = "";
string strTest2 = string.Empty;
string strTest3 = null;
//字符串是否相等
Console.WriteLine(strTest1==strTest2); //true
Console.WriteLine(strTest1 == strTest3); //false
Console.WriteLine(strTest2 == strTest3); //false
Console.WriteLine(strTest1.CompareTo(strTest2)); //0
Console.WriteLine(strTest1.CompareTo(strTest3)); //1
Console.WriteLine(strTest2.CompareTo(strTest3));//1
Console.WriteLine(strTest1.Equals(strTest2)); //true
Console.WriteLine(strTest1.Equals(strTest3)); //false
Console.WriteLine(strTest2.Equals(strTest3)); //false
Console.WriteLine(object.ReferenceEquals(strTest1,strTest2)); //false
Console.WriteLine(object.ReferenceEquals(strTest1, strTest3)); //false
Console.WriteLine(object.ReferenceEquals(strTest2, strTest3)); //false
string strTest4 = null;
Console.WriteLine(object.ReferenceEquals(strTest3, strTest4)); //true
Console.ReadLine();
}
}
}
(3)判定空字符串的几种写法
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest1 = "";
string strTest2 = string.Empty;
string strTest3 = null;
//字符串是否相等
Console.WriteLine(strTest1==strTest2); //true
Console.WriteLine(strTest1 == strTest3); //false
Console.WriteLine(strTest2 == strTest3); //false
Console.WriteLine(strTest1.CompareTo(strTest2)); //0
Console.WriteLine(strTest1.CompareTo(strTest3)); //1
Console.WriteLine(strTest2.CompareTo(strTest3));//1
Console.WriteLine(strTest1.Equals(strTest2)); //true
Console.WriteLine(strTest1.Equals(strTest3)); //false
Console.WriteLine(strTest2.Equals(strTest3)); //false
Console.WriteLine(object.ReferenceEquals(strTest1,strTest2)); //false
Console.WriteLine(object.ReferenceEquals(strTest1, strTest3)); //false
Console.WriteLine(object.ReferenceEquals(strTest2, strTest3)); //false
string strTest4 = null;
Console.WriteLine(object.ReferenceEquals(strTest3, strTest4)); //true
Console.ReadLine();
}
}
}
Code
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest1 = "";
string strTest2 = string.Empty;
string strTest3 = null;
//判定是否为空字符串,性能从高到低的顺序是s.Length == 0 优于 s == string.Empty 优于 s == ""
Console.WriteLine(strTest1.Length == 0); //true
Console.WriteLine(strTest2.Length == 0); //true
//Console.WriteLine(strTest3.Length==0); //异常
Console.WriteLine(strTest1 == string.Empty); //true
Console.WriteLine(strTest1 == null); //false
//最后,判定是否为空字符串的通用函数string.IsNullOrEmpty(s)
Console.WriteLine(string.IsNullOrEmpty(strTest1)); //true
Console.WriteLine(string.IsNullOrEmpty(strTest2)); //true
Console.WriteLine(string.IsNullOrEmpty(strTest3)); //true
Console.ReadLine();
}
}
}
二、JavaScript中的null,""和undefined
using System;
using System.Collections;
using System.Collections.Generic;
namespace MyCsStudy
{
class Program
{
static void Main(string[] args)
{
string strTest1 = "";
string strTest2 = string.Empty;
string strTest3 = null;
//判定是否为空字符串,性能从高到低的顺序是s.Length == 0 优于 s == string.Empty 优于 s == ""
Console.WriteLine(strTest1.Length == 0); //true
Console.WriteLine(strTest2.Length == 0); //true
//Console.WriteLine(strTest3.Length==0); //异常
Console.WriteLine(strTest1 == string.Empty); //true
Console.WriteLine(strTest1 == null); //false
//最后,判定是否为空字符串的通用函数string.IsNullOrEmpty(s)
Console.WriteLine(string.IsNullOrEmpty(strTest1)); //true
Console.WriteLine(string.IsNullOrEmpty(strTest2)); //true
Console.WriteLine(string.IsNullOrEmpty(strTest3)); //true
Console.ReadLine();
}
}
}
编程世界里只有 数据和代码两种基本元素。javascript中代码只体现为一种形式即function。javascript中数据则可以总结为简单数据和复杂数据两种。其中复杂数据只有一种即object,而简单数据包含null,undefined,boolean,number和string这五种。
下面简要介绍一下简单数据类型:
null 和c#差距很大(引用类型?),可以理解为有那么一个概念,但没有东西。
ps:typeof(null)返回object,但null并不是object,
具有null值的变量也并非object
undefined 代表一切未知事物,什么也没有。我们熟知的window对象
就有一个undefined属性。可以将undefined赋值给任何变量或属性,
但并不意味着消除了改变量,反而会因此多了一个属性。
ps:typeof(undefined)返回undefined
boolean true或者false,对就对,错就错,绝对明确,没有疑义
number 数值类型,线性事物,大小和次序分明,多而不乱,便于代码进行批量处理,
也控制代码的迭代和循环等
ps:typeof(NaN)和typeof(Infinity)都返回number。NaN参与任何数值计算
的结果都是NaN,而且NaN!=NaN. Infinity/Infinity=NaN.
string 字符串类型,面向人类的理性事物,非常适合人机编程交流,直接高效
千万注意,上面的单词都是小写的,不要和javascript内置函数Boolean,Number,String,Object,Function等混淆。
ps:typeof(null)返回object,但null并不是object,
具有null值的变量也并非object
undefined 代表一切未知事物,什么也没有。我们熟知的window对象
就有一个undefined属性。可以将undefined赋值给任何变量或属性,
但并不意味着消除了改变量,反而会因此多了一个属性。
ps:typeof(undefined)返回undefined
boolean true或者false,对就对,错就错,绝对明确,没有疑义
number 数值类型,线性事物,大小和次序分明,多而不乱,便于代码进行批量处理,
也控制代码的迭代和循环等
ps:typeof(NaN)和typeof(Infinity)都返回number。NaN参与任何数值计算
的结果都是NaN,而且NaN!=NaN. Infinity/Infinity=NaN.
string 字符串类型,面向人类的理性事物,非常适合人机编程交流,直接高效
下面比较一下null,""和undefined的异同点。
1、typeof的结果比较
Code
function funcTest()
{
var obj=null;
var str="";
alert(typeof(obj)); //object
alert(typeof(str)); //string
alert(typeof("undefined")); //string
alert(typeof(undefined)); //undefined
alert(typeof(window.undefined)); //undefined 和上一个等价
}
2、length属性比较
function funcTest()
{
var obj=null;
var str="";
alert(typeof(obj)); //object
alert(typeof(str)); //string
alert(typeof("undefined")); //string
alert(typeof(undefined)); //undefined
alert(typeof(window.undefined)); //undefined 和上一个等价
}
function
funcTest()
{
var obj = null ;
var str = "" ;
// alert(obj.length); //null没有length属性
alert(str.length); // 0
// alert(undefined.length); //undefined没有length属性
}
3、相等比较
{
var obj = null ;
var str = "" ;
// alert(obj.length); //null没有length属性
alert(str.length); // 0
// alert(undefined.length); //undefined没有length属性
}
(1)“==”
关于相等,要多看几个示例:
a、null,"",0和undefined转为逻辑值的情况
Code
function funcTest()
{
var obj=null;
var str="";
var num=0;
// null,"",0和undefined转换为逻辑值时都是false
if(!obj) alert("obj判定为否");
if(!str) alert("str判定为否");
if(!num) alert("num判定为否");
if(!undefined) alert("undefined判定为否");
//但是null和undefined又不直接==false
alert(obj==false); //false
alert(undefined==false); //false
//而""和0直接==false 怪怪怪
alert(str==false); //true
alert(num==false); //true
}
ps:除了false外加上null,0,"",
NaN(NaN比较特殊,有个isNaN方法可以直接判断)和undefined之外,其他任何东西(简单类型值,对象或者函数)转换为逻辑值时都是true。最怪的是:
function funcTest()
{
var obj=null;
var str="";
var num=0;
// null,"",0和undefined转换为逻辑值时都是false
if(!obj) alert("obj判定为否");
if(!str) alert("str判定为否");
if(!num) alert("num判定为否");
if(!undefined) alert("undefined判定为否");
//但是null和undefined又不直接==false
alert(obj==false); //false
alert(undefined==false); //false
//而""和0直接==false 怪怪怪
alert(str==false); //true
alert(num==false); //true
}
b、null,0,""和undefined各自相等吗?
Code
function funcTest()
{
var obj=null;
var str="";
var num=0;
alert(obj==undefined); //true null竟然又等于undefined
//""和0直接==false 怪怪怪
alert(str==false); //true
alert(num==false); //true
alert(obj==num); //false
alert(obj==str); //false
alert(obj==false); //false
alert(undefined==num); //false
alert(undefined==str); //false
alert(undefined==false); //false
}
从运行的结果看,除了null==undefined,""==false和0==false返回值为真之外,其他都不相等。js的灵活可见一斑。
function funcTest()
{
var obj=null;
var str="";
var num=0;
alert(obj==undefined); //true null竟然又等于undefined
//""和0直接==false 怪怪怪
alert(str==false); //true
alert(num==false); //true
alert(obj==num); //false
alert(obj==str); //false
alert(obj==false); //false
alert(undefined==num); //false
alert(undefined==str); //false
alert(undefined==false); //false
}
(2)全等("===")
function
funcTest()
{
var obj = null ;
var str = "" ;
alert(obj === str); // false
alert(obj === undefined); // false
alert(str === undefined); // false
}
关于相等==讨论到这里本来就可以了,可是考虑到实际开发中的需要,我们额外记录一点经验之谈:
{
var obj = null ;
var str = "" ;
alert(obj === str); // false
alert(obj === undefined); // false
alert(str === undefined); // false
}
(3)、数字和字符串比较
Code
function funcTest()
{
var str="123";
var num=123;
var num2=0123;
alert(str==num); //true
alert(str===num); //false 数据值和数据类型都相等才全等
alert(str==num2); //false
alert(num==num2); //false js将以“0”开头的整数当八进制数处理
var str2="0123";
alert(num2==str2); //false
alert(num==parseInt(str2,10)); //true 转化为10十进制就相等了
}
4、与数值和字符串运算时
function funcTest()
{
var str="123";
var num=123;
var num2=0123;
alert(str==num); //true
alert(str===num); //false 数据值和数据类型都相等才全等
alert(str==num2); //false
alert(num==num2); //false js将以“0”开头的整数当八进制数处理
var str2="0123";
alert(num2==str2); //false
alert(num==parseInt(str2,10)); //true 转化为10十进制就相等了
}
function
funcTest()
{
var num = 123 ;
alert(num + null ); // 123
alert(num + undefined); // NaN
var str = " 123 " ;
alert(str + null ); // 123null
alert(str + undefined); // 123undefined
}
可见,与数值运算时,null参与数值运算时其值会自动转换为0,而undefined参与任何数值计算时,其结果一定是NaN;
{
var num = 123 ;
alert(num + null ); // 123
alert(num + undefined); // NaN
var str = " 123 " ;
alert(str + null ); // 123null
alert(str + undefined); // 123undefined
}
对于字符串运算,把null和undefined原封不动”连接“就可以了。
5、是否关键字
null是javascript保留关键字,而undefined是有特殊含义的属性,但却不是javascript的保留关键字。
至于说undefined是特殊含义的属性,看代码:
function
funcTest()
{
alert( ' undefined ' in window); // true
alert(undefined in window); // true
var obj = {};
alert( ' undefined ' in obj); // false
alert(undefined in obj); // false
}
这证明undefined是window对象的属性。
{
alert( ' undefined ' in window); // true
alert(undefined in window); // true
var obj = {};
alert( ' undefined ' in obj); // false
alert(undefined in obj); // false
}
ps:NaN和Infinity是window对象的另外两个特殊属性。这俩特殊属性都不是javascript的保留关键字.
ok,浅显地总结一下。从上面的篇幅中,你看不出它们的本质方面的东西,但是关于“空”这个东东在平时的项目中几乎都会碰到(笔者不止一次两次地碰到过在方法体中null然后ToString()一下,虽然也知道null不能这么干,但是你不能保证他人写好的方法被你调用,null的情况有没有特殊考虑一下),希望能引起你的注意并对你有用。欢迎补充。