- 对象里面的一切都是属性,只有属性,没有方法。那么这样方法如何表示呢?——方法也是一种属性。因为它的属性表示为键值对的形式。
2. 一切(引用类型)都是对象,对象是属性的集合.函数也是一种对象,对象是通过函数创建的,JavaScript默认给函数一个属性prototype,即每个函数都有一个属性叫做prototype,这个prototype的属性值是一个对象(属性的集合),默认的只有一个叫做constructor的属性,指向这个函数本身。
3. 每个对象都有一个隐藏的属性__proto__,这个属性指向创建这个对象的函数的prototype。即:
function Person() { };
Person.prototype.name = "alisa";
Person.prototype.getYear = function () {
return "1988";
};
var p1 = new Person();
p1.__proto__ === Person.prototype;(true)
4. Javascript中的继承概念与Java中的概念完全不同,JavaScript中的继承是通过原型链来体现的。
5. 自定义的函数是都是由函数Function创建的,
6. 访问某个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链。
function Person() { }
Person.prototype.name = "alisa";
Person.prototype.age = "12";
Person.prototype.getYear = function () {
return "1988";
};
var p1 = new Person();
p1.name = "yuanhui";
console.log(p1.name); (yuanhui)
console.log(p1.age); (12)
7. 如何区分一个属性到底是对象的基本属性还是从原型中得到的呢?使用hasOwnProperty,一般在for ...in..循环中用的最多。
function Person() { }
Person.prototype.name = "alisa";
Person.prototype.age = "12";
Person.prototype.getYear = function () {
return "1988";
};
var p1 = new Person();
p1.name = "yuanhui";
for (var item in p1) {
if (p1.hasOwnProperty(item)) {
console.log(item); (name)
}
}
8. 所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。这就是所谓的“继承”。
9. JavaScript中对象属性可以随时改动。
10. 在一段js代码拿过来真正一句一句运行之前,浏览器已经做了一些“准备工作”,其中就包括对变量的声明,而不是赋值。变量赋值是在赋值语句执行的时候进行的。
11. JS解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。
12. 在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。因为this的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境。
情况1:构造函数
function Person(name,age){
this.name=name;
this.age=age;
console.log(this); //person {name: "alisa", age: 20}
}
var p=new Person("alisa",20);
如果函数是作为构造函数使用,那么其中的this就代表它即将new出来的对象。注意:以上仅限于使用Person()函数作为构造函数使用,如果直接调用Person()函数,情况就不一样了。
function Person(name,age){
this.name=name;
this.age=age;
console.log(this); // Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
}
Person("alisa",20);
情况2:函数作为对象的一个属性
var p = {
name:10,
getAge:function(){
console.log(this);// Object {name: 10, getAge: function}
}
};
p.getAge();
如果函数作为对象的一个属性被调用时,函数中的this指向该对象。如果函数作为对象的一个属性,但是并没有被直接调用,而是被赋值给另一个变量中,情况又不一样了。
var p = {
name:10,
getAge:function(){
console.log(this);// Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
}
};
var p1=p.getAge;
p1();
情况3:函数用call或者apply调用
var animal={
getName:function(name){
this.name=name;
console.log(this);// Object {name: "miaomiao"}
}
}
var cat={
}
animal.getName.call(cat,"miaomiao");
如果函数被call或者apply调用,this值就是传入对象的值。
情况4:全局或者调用普通函数
在全局环境下,this永远指向window,普通函数在调用时,其中的this也指向window
13. javascript除了全局作用域之外,只有函数可以创建的作用域。作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
14. 闭包是指有权访问另一个函数作用域的变量的函数,创建闭包最常见的方式就是在一个函数内部创建另一个函数,在另一个函数中访问这个函数的局部变量。
15. 闭包的缺点就是常驻内存,这样会增大内存的使用量,使用不当容易造成内存泄露。一般函数执行完毕以后,局部活动对象就被销毁,内心中仅仅保存全局作用域,但是闭包的情况不同!
16. 闭包是JavaScript的一大特点,主要应用闭包的场合是为了:设计私有方法和变量。使用闭包的好处:1)、希望一个变量长期驻扎在内存中;2)、避免全局变量的污染;3)、私有成员存在
17. 闭包应用的情况有2种:函数作为返回值;函数作为参数传递。
情况1:函数作为返回值
function person(){
var maxAge=20;
return function getAge(age){
if(age>maxAge){
console.log("you are so old."); // you are so old.
}
};
}
var p=person();
p(26);
情况2:函数作为参数传递
var maxAge=20;
var p=function(age){
if(age>maxAge){
console.log("you are so old");// you are so old
}
};
(function (showAge){
var maxAge=30;
showAge(26);
})(p);
自由变量跨作用域取值时:要去创建这个函数的作用域取值,而不是“父作用域”.