一.变量类型和计算
1.值类型 vs 引用类型
值类型 ,特点:每个变量都能存储各自的值,不会相互影响。var a = 100; var b = a; a = 200; console.log(b); //100
上面不光number类型是这个结果,像string,boolean,undefined类型也是一样的结果。
引用类型,包括对象,数组,函数。
var a = {age: 21}; var b = a; b.age = 100; console.log(a.age); //100
比较上面两个例子:值类型在运算的过程中,如果将一个变量赋值给另一个变量,会把值复制一份给它。
而引用类型并不会复制一份给它,因为引用类型一般都比较大,如果复制一份过去的话很消耗内存,所以引用类型赋值给另一个变量的时候,实质是指向一个对象类型的指针。
2.typeof运算符
console.log(typeof(undefined)); //undefined console.log(typeof('abc')); //string console.log(typeof(123)); //number console.log(typeof(true)); //boolean console.log(typeof({})); //object console.log(typeof([])); //object console.log(typeof(null)); //object console.log(typeof(console.log)); //function从上面例子可以看出。1. typeof运算符只能区分值类型的数据类型 。2.typeof运算符的结果有六种,分别是:
string number undefined boolean object function
3.变量计算----强制类型转换。
字符串拼接
var a = 100 + 10; //110 var b = 100 + "10"; //10010 这个是string类型 ==运算符
100 == '100'; //true 0 == ''; //true null == undefined; //true
从上面结果可以看出来,我们要谨慎使用==运算符。
if语句
var a = true; if (a) { //... } var b = 100; if (b) { //... } var c = ''; if (c) { //... }
逻辑运算符
console.log(10 && 0); //0 console.log('' || 'abc'); //'abc' console.log(!window.abc); //true //判断一个变量会被当作true还是false var a = 100; console.log(!!a); //true1.问题:何时使用 === ,何时使用 ==?
if (obj.a == null) { //推荐使用jQuery的写法,即我们需要判断的如obj.a === null || obj.a === undefined的时候我们使用==符号
(obj.a == null,相当于obj.a === null || obj.a === undefined)。别的情况都使用===符号。 }
2.问题:js中有哪些内置函数
Object Array String Number Boolean Function Date RegExp Error
3.问题:js按存储方式分为哪几种类型,各自有哪些特点?
1.值类型,特点:每一个变量的值分块存储在内存当中。
2.引用类型,特点:变量共用一个内存块,为了节省内存空间。
4.如何理解JSON?
JSON和Math一样,是一个JS对象,JSON同时还是一种格式。
json提供两种API:
var a = JSON.stringify({a:10, b:20}); //转换为字符串 console.log(typeof(a)); //string var b = JSON.parse('{"a":10, "b":20}'); //转换成对象 console.log(typeof(b)); //object
二.原型和原型链-----构造函数
构造函数
构造函数和普通函数的区别:
一般规则:构造函数都应该以大写字母开头,eg: function Person() {...}
非构造函数都应该以小写字母开头,eg: function person() {...}
调用方式:任何函数,只要它能够通过new操作符来调用,那么它就可以作为构造函数;如果没用通过new操作符调用,那它和普通函数就没有区别。
function Person(name,age,job) { this.name = name; this.age = age; this.job = job; this.sayName = function() { alert(this.name); } } //当作构造函数使用 var person = new Person("zhangsan", 22, "doctor"); //this ==> person person.sayName(); //"zhangsan" //当作普通函数使用 Person("lisi", 30, "teacher"); //this ==> window window.sayName(); //"lisi"构造函数----扩展
1.var a = {} 其实是 var a = new Object() 的语法糖,即他的构造函数是Object
2.var a = [] 其实是 var a = new Array() 的语法糖,即他的构造函数是Array
3.function Foo() {...} 其实是 var Foo = new Function(....),即他的构造函数是Function
4.使用instanceof判断一个函数是否是一个变量的构造函数
注:实际开发中推荐使用前面这种简便的写法。
原型规则
5条原型规则,原型规则是学习原型链的基础。
1.所有的引用类型(数组,对象,函数),都具有对象特性,即可自由扩展属性(除了null以外)。
2.所有的引用类型(数组,对象,函数),都有一个__proto__(隐式原型)属性,属性值是一个普通的对象。
3.所有的函数,都有一个prototype(显示原型)属性,属性值也是一个普通的对象。
4.所有的引用类型(数组,对象,函数),__proto__属性值指向他的构造函数的prototype属性值。
var obj = {}; obj.a = 100; var arr = []; arr.a = 100; function fn () {} fn.a = 100; console.log(obj.__proto__); console.log(arr.__proto__); console.log(fn.__proto__); console.log(fn.prototype); console.log(obj.__proto__ === Object.prototype);
5.当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去他的__proto__(即它的构造函数的prototype)中寻找。
//构造函数 function Foo(name,age) { this.name = name; } Foo.prototype.alertName = function () { alert(this.name); } //创建实例 var f = new Foo('zhangsan'); f.printName = function() { console.log(this.name); } //测试 f.printName(); f.alertName(); //f中找不到alertName这个属性,根据第五条原型规则会去f的__proto__属性中寻找,
即去f的构造函数Foo中的prototype属性中寻找。注意:js中this永远指向的是最后调用它的对象
小知识:循环对象自身的属性:
var item; for (item in f) { //高级浏览器已经在for in 中屏蔽了来自原型的属性 //但是这里建议大家还是加上这个判断。保证程序的健壮性 if (f.hasOwnproperty(item)) { console.log(item); } }
原型链
function Foo(name,age) { this.name = name; } Foo.prototype.alertName = function () { alert(this.name); } //创建实例 var f = new Foo('zhangsan'); f.printName = function() { console.log(this.name); } //测试 f.printName(); f.alertName(); f.toString(); //去f.__proto__.__proto__中找

原型链----instanceof
用于判断引用类型属于哪个构造函数的方法。
f instanceof Foo 的判断逻辑是:
1.f 的__proto__一层一层往上,能否对应到Foo.prototype。
2.再试着判断f instanceof Object。
问题1:如何准确判断一个变量是数组类型?
var one = []; console.log(one instanceof Array); //true console.log(typeof(one)); //object,typeof是判断不了的问题2:写一个原型链继承的例子。
写一个封装DOM查询的例子:
function Elem (id) { this.elem = document.getElementById(id); } Elem.prototype.html = function (val) { var elem = this.elem; if (val) { elem.innerHTML = val; return this; //链式操作,关键在于return this,使用了他就相当于返回了p1,不写它自己也会返回 } else { return elem.innerHTML; } } Elem.prototype.on = function (type, fn) { var elem = this.elem; elem.addEventListener(type, fn); return this; } var p1 = new Elem("p1"); /*console.log(p1.html());*/ /*p1.html("
hello world
"); p1.on("click", function () { console.log('click'); })*/ //上面注释的代码,我们使用链式语法来执行,理解一下链式语法 p1.html("hello world
").on("click", function(){console.log("click")});问题3:描述new一个对象的过程。
1.创建一个新对象。2.this指向这个新对象。 3.执行代码,即对this赋值。 4.返回this。