""
、0
、NaN
、undefined
、null
会在if ()
中自动转换成false
,其余都为true
。String
转Int
最快捷的方式var str = '1'; +str
,运算中需要加括号1 + (+str)
。有字符串参与的加法运算,则全部转为
String
类型运行,其他运算法则(-,*,/,%)
都全部转为Number
类型运算。undefined
表示值类型的空值,null
表示指针类型的空值。正则表达式、函数、对象、数组,都是引用类型,其余都是值类型。
所谓引用类型,即:
var obj = {}
,相当于0x01010101 <==> {}; obj = 0x01010101
,而var obj2 = obj
中传递的其实是0x01010101
,0x01010101
为假设的指针。匿名函数的调用:
(function(){})(); // 正常
(function(){}()); // 正常
~function(){}(); // 正常
+function(){}(); // 正常
function(){}(); // 报错
// 前4个的结果是一样的
-
new
与方法同一行调用:
function ClassA() { }
ClassA.prototype.say = function() { console.log('prototype'); }
ClassA.say = function() { console.log('constructor'); }
new ClassA().say(); // prototype 相当于 (new ClassA()).say()
new ClassA.say(); // constructor 相当于 new (ClassA.say())
-
typeof
用于检测变量的类型:
typeof 'a' => string
typeof 1/1.1/NaN => number
typeof true => boolean
typeof undefined => undefined
typeof function (){} => function
typeof {}、[]、null、/a/ => object
-
instanceof
用于识别对象属于哪个类或其父类:
function Class1 () {}
function Class2 () {}
var class1 = new Class1;
class1 instanceof Class1; => true
class1 instanceof Object; => true
class1 instanceof Class2; => false
- 变量的作用域提升:
alert(a); // 报错,a未定义
alert(a); // undefined
var a = 'a';
// ---------- 相当于 ----------
var a;
alert(a);
a = 'a';
- 函数的作用域提升:
b(); // 调用成功
function b() {
alert('b');
}
c(); // c = undefined,报错
var c = function () {
alert('c');
}
- 类的定义
function Class1(name) {
this.name = name;
}
Class1.prototype.setAge = function(age) {
this.age = age;
}
var class1 = new Class1('class1');
class1.setAge(10);
- 类的继承
function Class2(time) {
Class1.call(this, 'orange');
this.time = time;
}
Class2.prototype = Object(Class1.prototype);
Class2.prototype.constructor = Class2;
var class2 = new Class2(10);
class2.setAge(20);
-
this
的指向
function Animal() {
console.log(this);
}
var animal = new Animal(); // this 指向 Animal
function Animal() {
console.log(this);
}
function Dog() {
console.log(this);
Animal.call(this);
}
var dog = new Dog(); // 由于 Animal 的调用传入 Dog 的 this,两个的 this 都指向 Dog
var obj = {
fn: function() {
console.log(this);
}
}
obj.fn();
// -------------- 相当于 ---------------
var obj = new Object;
obj.fn = function() {
console.log(this);
}
obj.fn(); // this 为 obj 对象的 Object 类
var obj = {
fns: {
fn: function() {
console.log(this);
}
}
}
obj.fns.fn(); // this 指向 fns 对象的 Object 类
// ---------------- 相当于 ----------------
var obj = new Object;
var fns = new Object;
fns.fn = function() {
console.log(this);
}
obj.fns = fns;
obj.fns.fn();
function fn(){
console.log('outer: ' + this);
return function () {
console.log('inner: ' + this);
}
}
var closure = fn.call({}); // outer: Object
closure(); // inner: window
// this 的值是根据调用时的上下文,而不是定义时的上下文。
function fn() {
console.log(this);
}
fn(); // 无实例化过程,默认 this 为全局对象 Global,浏览器中为 window
-
prototype
原型链
· 类有 prototype ,对象没有 prototype:
function Class1() { }
var instance1 = new Class1;
console.log(Class1.prototype); // Object {constructor: function}
console.log(instance1.prototype); // undefined
· 对象通过 __proto__
属性访问类的 prototype
:
function Class1() { }
var instance1 = new Class1;
console.log(Class1.prototype); // Object {constructor: function}
console.log(instance1.__proto__); // Object {constructor: function}
console.log(Class1.prototype === instance1.__proto__); // true
· prototype
方法与构造函数中的方法的区别:
function Class1() {
this.setName = function (name) {
}
}
Class1.prototype.setAge = function () {
}
var instance1 = new Class1;
var instance2 = new Class1;
console.log(instance1.setName === instance2.setName); // false
console.log(instance1.setAge === instance2.setAge); // true
// 构造函数中的方法每次实例化都会重新复制一个函数实体,
// 会造成实例化过程中多余的内存消耗,在面向对象编程概念中是错误。
· prototype
属性与构造函数中的属性的区别:
function Class1() {
this.name = "";
}
Class1.prototype.age = 0;
var instance1 = new Class1;
var instance2 = new Class1;
instance1.name = 'instance1';
instance2.age = 10;
console.log(instance1.age); // 0
console.log(instance2.age); // 10
console.log(instance1); // Class1 {name: "instance1"}
console.log(instance2); // Class1 {name: "", age: 10}
console.log(instance1.__proto__); // Object {age: 0, constructor: function}
console.log(instance2.__proto__); // Object {age: 0, constructor: function}
// 可以发现,访问属性时,优先访问构造函数中同名属性,如果没有,
// 再访问 __proto__ 中的,而赋值属性时,是无法给 prototype 中的属性赋值的。
· 类继承中的 prototype
function God() { }
God.prototype.fly = function() { }
function Parent() { }
Parent.prototype = new God;
Parent.prototype.run = function() { }
function Children() { }
Children.prototype = new Parent;
Children.prototype.walk = function() { }
var boy = new Children;
console.log(boy.__proto__); // {walk: function}
console.log(boy.__proto__.__proto__); // {run: function}
console.log(boy.__proto__.__proto__.__proto__); // {fly: function, constructor: function}
console.log(boy.fly); // function () { }
// 在对象访问属性或方法时,会不断向对象中的 __proto__ 查找,
// 如果上一级找不到,会继续查找 __proto__.__proto__ ,最终找不到则会返回 undefined。