null和undefined的区别

356 阅读4分钟

原型规则

原型规则

所有的引用类型(数组、对象、函数),都具有对象特征,即可自由扩展属性;

var arr = []; arr.a =1;
  • 所有的引用类型都有对象的特性,即可自由扩展
  • 所有的引用类型都有一个_proto_属性(隐式原型),属性的值是一个普通对象
  • 所有函数,都具有一个prototype(显示原型),属性值也是一个普通原型
  • 所有的引用类型(数组、对象、函数),其隐式原型指向其构造函数的显式原型;(obj.proto === Object.prototype)
  • 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么回去它的_proto_(即它的构造函数的prototype)中去寻找

原型对象

prototype 在js中,函数对象其中一个属性:原型对象prototype。普通对象没有prototype属性,但有_proto_属性。 原型的作用就是给这个类的每一个对象都添加一个统一的方法,在原型中定义的方法和属性都是被所以实例对象所共享。

var person = function(name){
    this.name = name
};
person.prototype.getName=function(){//通过person.prototype设置函数对象属性
    return this.name; 
}
var crazy= new person(‘crazyLee’);
crazy.getName(); //crazyLee//crazy继承上属性

原型链

当试图得到一个对象f的某个属性时,如果这个对象本身没有这个属性,那么会去它的_proto_(即它的构造函数的prototype)obj._proto_中去寻找;当obj._proto也没有时,便会在obj._proto.proto(即obj的构造函数的prototype的构造函数的prototype)中寻找

设计模式

工厂模式

在函数内创建一个对象,给对象赋予属性及方法再将对象返回

function Person() {
	var People = new Object();
	People.name = 'CrazyLee';
	People.age = '25';
	People.sex = function(){
		return 'boy';
	};
	return People;
}

var a = Person();
console.log(a.name);//CrazyLee
console.log(a.sex());//boy

构造函数模式

无需在函数内部重新创建对象,而是用this指代

function Person() {
	this.name = 'CrazyLee';
	this.age = '25';
	this.sex = function(){
		return 'boy'
	};
	
}

var a = new Person();
console.log(a.name);//CrazyLee
console.log(a.sex());//boy

原型模式

函数中不对属性进行定义,利用prototype属性对属性进行定义,可以让所有对象实例共享它所包含的属性及方法

function Parent() {
	Parent.prototype.name = 'carzy';
	Parent.prototype.age = '24';
	Parent.prototype.sex = function() {
	 var s="女";

    console.log(s);
	}
}

var  x =new  Parent();  
console.log(x.name);      //crazy
console.log(x.sex());       //女

混合模式

原型模式+构造函数模式。这种模式中,构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性

function Parent(){  
	this.name="CrazyLee";  
	this.age=24;  
};
Parent.prototype.sayname=function(){  
	return this.name;  
};

var x =new Parent(); 
console.log(x.sayname());   //Crazy  

动态原型模式

将所有信息封装在了构造函数中,而通过构造函数中初始化原型,这个可以通过判断该方法是否有效而选择是否需要初始化原型

function Parent(){  
	this.name="CrazyLee";  
	this.age=24;  
	if(typeof Parent._sayname=="undefined"){     
		Parent.prototype.sayname=function(){  
			return this.name;  
		}  
		Parent._sayname=true;  
	}         
};   

var x =new Parent();  
console.log(x.sayname()); 

 参考:《原型设计模式以及JavaScript中的原型规则》

undefined

undefined 的字面意思就是:未定义的值 。这个值的语义是,希望表示一个变量最原始的状态,而非人为操作的结果 。 这种原始状态会在以下 4 种场景中出现:

声明一个变量,但是没有赋

var foo;
console.log(foo); // undefined

访问 foo,返回了 undefined,表示这个变量自从声明了以后,就从来没有使用过,也没有定义过任何有效的值。

访问对象上不存在的属性或者未定义的变量

console.log(Object.foo); // undefined
console.log(typeof demo); // undefined

访问 Object 对象上的 foo 属性,返回 undefined , 表示Object 上不存在或者没有定义名为 foo 的属性;对未声明的变量执行typeof操作符返回了undefined值。

函数定义了形参,但没有传递实参

//函数定义了形参 a
function fn(a) {
    console.log(a); // undefined
}
fn(); //未传递实参

函数 fn 定义了形参 a,但 fn 被调用时没有传递参数,因此,fn 运行时的参数 a 就是一个原始的、未被赋值的变量。

使用void对表达式求值

void 0 ; // undefined
void false; // undefined
void []; // undefined
void null; // undefined
void function fn(){} ; // undefined

null

null 的字面意思是:空值 。这个值的语义是,希望表示一个对象被人为的重置为空对象,而非一个变量最原始的状态 。 在内存里的表示就是,栈中的变量没有指向堆中的内存对象。

特殊的typeof null

let data = null;
console.log(typeof data); // "object"

 相同点

值相同

console.log( undefined == null )//true

转换Boolean的都是false

console.log( Boolean(undefined) )//false
console.log( Boolean(null) )//false

不同点

数据类型不同

console.log( undefined === null )//false     

转换为Number类型的值不同

console.log( Number(undefined) )//NaN
console.log( Number(null) )//0

总结

  • undefined相当于期房。 买了房,但是房子还没建出来。(未定义)

  • null相当于毛坯房。买了房,但是房子没住人,里面是空的。(空值)

  • 值是undefined的变量和未声明的变量,typeof运算结果都是“undefined”。运算符typeof运算null的类型时返回“object”。

  • 通过禁止使用特殊值undefined,可以有效地确保只在一种情况下typeof才会返回“undefined”:当变量未声明时。这样就可以区别null和undefined。

ps:文末附上汇总文章链接《一名【合格】前端工程师的自检清单【自检ing】》