这里有一份简洁的前端知识体系等待你查收,看看吧,会有惊喜哦~若是以为不错,恳求star哈~前端
原始类型 保存为简单数据值。 引用类型 保存为对象,其本质是指向内存位置的引用。git
为了让开发者可以把原始类型和引用类型按相同的方式处理,JavaScript 花费了很大的努力来保证语言的一致性。github
其余编程语言用栈存原始类型,用对存储引用类型。正则表达式
而 JavaScript 则彻底不一样:它使用一个变量对象追踪变量的生存期。编程
原始值被直接保存在变量对象内,而引用值则做为一个指针保存在变量对象内,该指针指向实际对象在内存中的存储位置。数组
原始类型表明照原样保存的一些简单数据。app
JavaScript 共有5种原始类型:框架
true
or false
JavaScript 和许多其余语言同样,原始类型的变量直接保存原始值(而不是一个指向对象的指针)。编程语言
var color1 = "red";
var color2 = color1;
console.log(color1); // "red"
console.log(color2); // "red"
color1 = "blue";
console.log(color1); // "blue"
console.log(color2); // "red"
复制代码
鉴别原始类型的最佳方式是使用 typeof
操做符。函数
console.log(typeof "Nicholas"); // "string"
console.log(typeof 10); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
复制代码
至于空类型(null)则有些棘手。
console.log(typeof null); // "object"
复制代码
对于 typeof null,结果是"object"。(其实这已被设计和维护 JavaScript 的委员会 TC39 认定是一个错误。在逻辑上,你能够认为 null
是一个空的对象指针,因此结果为"object",但这仍是很使人困惑。)
判断一个值是否为空类型(null)的最佳方式是直接和 null
比较:
console.log(value === null); // true or false
复制代码
注意:以上这段代码使用了三等号(全等 ===),由于三等号(全等)不会将变量强制转换为另外一种类型。
console.log("5" == 5); // true
console.log("5" === 5); // false
console.log(undefined == null); // true
console.log(undefined === null); // false
复制代码
虽然字符串、数字和布尔值是原始类型,可是它们也拥有方法(null 和 undefined 没有方法)。
var name = "Nicholas";
var lowercaseName = name.toLowerCase(); // 转为小写
var count = 10;
var fixedCount = count.toFixed(2); // 转为10.00
var flag = true;
var stringFlag = flag.toString(); // 转为"true"
console.log("YIBU".charAt(0)); // 输出"Y"
复制代码
尽管原始类型拥有方法,但它们不是对象。JavaScript 使它们看上去像对象同样,以此来提升语言上的一致性体验。
引用类型是指 JavaScript 中的对象,同时也是你在该语言中能找到最接近类的东西。
引用值是引用类型的实例,也是对象的同义词(后面将用对象指代引用值)。
对象是属性的无序列表。属性包含键(始终是字符串)和值。若是一个属性的值是函数,它就被称为方法。
除了函数能够运行之外,一个包含数组的属性和一个包含函数的属性没有什么区别。
有时候,把 JavaScript 对象想象成哈希表能够帮助你更好地理解对象结构。
JavaScript 有好几种方法能够建立对象,或者说实例化对象。第一种是使用 new
操做符和构造函数。
构造函数就是经过 new
操做符来建立对象的函数——任何函数均可以是构造函数。根据命名规范,JavaScript 中的构造函数用首字母大写来跟非构造函数进行区分。
var object = new Object();
复制代码
由于引用类型再也不变量中直接保存对象,因此本例中的 object
变量实际上并不包含对象的实例,而是一个指向内存中实际对象所在位置的指针(或者说引用)。这是对象和原始值之间的一个基本差异,原始值是直接保存在变量中。
当你将一个对象赋值给变量时,实际是赋值给这个变量一个指针。这意味着,将一个变量赋值给另一个变量时,两个变量各得到了一份指针的拷贝,指向内存中的同一个对象。
var obj1 = new Object();
var obj2 = obj1;
复制代码
JavaScript 语言有垃圾收集的功能,所以当你使用引用类型时无需担忧内存分配。但最好在不使用对象时将其引用解除,让垃圾收集器对那块内存进行释放。解除引用的最佳手段是将对象变量设置为 null
。
var obj1 = new Object();
// dosomething
obj1 = null; // dereference
复制代码
在 JavaScript 中,你能够随时添加和删除其属性。
var obj1 = new Object();
var obj2 = obj1;
obj1.myCustomProperty = "Awsome!";
console.log(obj2.myCustomProperty); // "Awsome!" 由于 obj1 和 obj2 指向同一个对象。
复制代码
内建类型以下:
可以使用 new
来实例化每个内建引用类型:
var items = new Array();
var now = new Date();
var error = new Error("Something bad happened.");
var func = new Function("console.log('HI');");
var object = new Object();
var re = new RegExp();
复制代码
内建引用类型有字面形式。字面形式容许你在不须要使用 new
操做符和构造函数显示建立对象的状况下生成引用值。属性的键能够是标识符或字符串(若含有空格或其余特殊字符)
var book = {
name: "Book_name",
year: 2016
}
复制代码
上面代码与下面这段代码等价:
var book = new Object();
book.name = "Book_name";
book.year = 2016;
复制代码
虽然使用字面形式并无调用 new Object(),可是 JavaScript 引擎背后作的工做和 new Object() 同样,除了没有调用构造函数。其余引用类型的字面形式也是如此。
可经过 .
和 中括号
访问对象的属性。 中括号 []
在须要动态决定访问哪一个属性时,特别有用。由于你能够用变量而不是字符串字面形式来指定访问的属性。
函数是最容易鉴别的引用类型,由于对函数使用 typeof
操做符时,返回"function"。
function reflect(value){
return value;
}
console.log(typeof reflect); // "function"
复制代码
对其余引用类型的鉴别则较为棘手,由于对于全部非函数的引用类型,typeof
返回 object
。为了更方便地鉴别引用类型,可使用 JavaScript 的 instanceof
操做符。
var items = [];
var obj = {};
function reflect(value){
return value;
}
console.log(items instanceof Array); // true;
console.log(obj instanceof Object); // true;
console.log(reflect instanceof Function); // true;
复制代码
instanceof
操做符可鉴别继承类型。这意味着全部对象都是 Oject
的实例,由于全部引用类型都继承自 Object
。
虽然 instanceof 能够鉴别对象类型(如数组),可是有一个列外。JavaScript 的值能够在同一个网页的不用框架之间传来传去。因为每一个网页拥有它本身的全局上下文—— Object、Array 以及其余内建类型的版本。因此当你把一个对象(如数组)从一个框架传到另一个框架时,instanceof 就没法识别它。
原始封装类型有 3
种:String、Number 和 Boolean。 当读取字符串、数字或布尔值时,原始封装类型将被自动建立。
var name = "Nicholas";
var firstChar = name.charAt(0); // "N"
复制代码
这在背后发生的事情以下:
var name = "Nichola";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
复制代码
因为第二行把字符串当成对象使用,JavaScript 引擎建立了一个字符串的实体让 charAt(0)
能够工做。字符串对象的存在仅用于该语句并在随后销毁(一种被称为自动打包的过程)。为了测试这一点,试着给字符串添加一个属性看看它是否是对象。
var name = "Nicholas";
name.last = "Zakas";
console.log(name.last); // undefined;
复制代码
下面是在 JavaScript 引擎中实际发生的事情:
var name = "Nicholas";
var temp = new String(name);
temp.last = "Zakas";
temp = null; // temporary object destroyed
var temp = new String(name);
console.log(temp.last);
temp = null;
复制代码
新属性 last
其实是在一个马上就被销毁的临时对象上而不是字符串上添加。以后当你试图访问该属性时,另外一个不一样的临时对象被建立,而新属性并不存在。
虽然原始封装类型会被自动建立,在这些值上进行 instanceof
检查对应类型的返回值倒是 false
。 这是由于临时对象仅在值被读取时建立。instanceof
操做符并无真的读取任何东西,也就没有临时对象的建立。
固然你也能够手动建立原始封装类型。
var str = new String("me");
str.age = 18;
console.log(typeof str); // object
console.log(str.age); // 18
复制代码
如你所见,手动建立原始封装类型实际会建立出一个 object
。这意味着 typeof
没法鉴别出你实际保存的数据的类型。
另外,手动建立原始封装类型和使用原始值是有必定区别的。因此尽可能避免使用。
var found = new Boolean(false);
if(found){
console.log("Found"); // 执行到了,尽管对象的值为 false
}
复制代码
这是由于一个对象(如 {}
)在条件判断语句中总被认为是 true
;
第一章的东西都是咱们一些比较熟悉的知识。可是也有一些须要注意的地方:
5
种原始类型均可以用 typeof 来鉴别,而空类型必须直接跟 null
进行全等比较。typeof
鉴别。其它引用类型,可用 instanceof
和一个构造函数来鉴别。(固然能够用 Object.prototype.toString.call()
鉴别,它会返回 [object Array]之类的)。3
种封装类型。JavaScript会在背后建立这些对象使得你可以像使用普通对象那样使用原始值。但这些临时对象在使用它们的语句结束时就马上被销毁。虽然可手动建立,但不建议。