网站开发图片加载过慢如何优化,学网页制作的好处,招远网站建设公司地址,wordpress一直有人登录1 对象相关的一些语言特性1.1 一切皆为对象JavaScript里所有的东西都是对象. 对象是属性的集合. 数字, 字符串, 布尔值等原始值是伪对象, 它们同样拥有属性, 但是是在栈上分配并按值传递. 而其他的对象是堆上分配并按引用传递.一个很重要的概念是, 函数也是对象, 能…1 对象相关的一些语言特性1.1 一切皆为对象JavaScript里所有的东西都是对象. 对象是属性的集合. 数字, 字符串, 布尔值等原始值是伪对象, 它们同样拥有属性, 但是是在栈上分配并按值传递. 而其他的对象是堆上分配并按引用传递.一个很重要的概念是, 函数也是对象, 能够作为变量的值, 返回值, 参数或者属性的值. 函数对象特殊的地方是能通过xxx()语法执行包含在xxx函数对象内的代码. 因为这一特殊性, typeof xxx 将会返回function, 但这只是一种便利设施.1.2 对象的属性可以动态添加和删除 var foo new Object();// 为foo对象添加bar属性foo.bar foobar;alert(foo.bar); //foobar// 删除foo对象的bar属性delete foo.bar;alert(foo.bar); //undefined 1.3 除了宿主对象, 其它对象皆由构造函数创建要有对象, 就先要有创建对象的方法. 在C/Java等语言, 这个方法就是实例化XXX类的一个实例xxx.而在JavaScript的世界里实际没有类的东西, 当然仍然可以用类和实例等惯用语来描述JavaScript中类似的行为, 但其机制是完全不同的. JavaScript的对象是由构造函数创建的, 每个对象都有constructor属性表示创建该对象的构造函数: function Test() { this.a hello; }var test new Test(); // 由Test构造函数创建alert(test.constructor);var o { a: hello };//实际相当于var o_ new Object();o_.a hello; // 由Object构造函数创建alert(o.constructor); 构造函数也是对象, 那构造函数是由什么创建? 内建的Function函数: function Test(a, b){ alert(ab);}// 相当于:Test new Function([a, b], alert(ab);); Function函数又是由什么创建? 实际上Function是本机代码实现的固有对象. 不过为了一致性, Function也有constructor属性, 该属性指向它自己. 接上面的代码: /* 输出 function Function(){ [native code] }*/alert(Test.constructor);alert(Test.constructor.constructor Test.constructor); // truealert(Test.constructor Object.constructor); // true 2 原型prototype2.1 prototype的概念prototype是构造函数的一个属性, 该属性指向一个对象. 而这个对象将作为该构造函数所创建的所有实例的基引用(base reference), 可以把对象的基引用想像成一个自动创建的隐藏属性. 当访问对象的一个属性时, 首先查找对象本身, 找到则返回; 若不, 则查找基引用指向的对象的属性(如果还找不到实际上还会沿着原型链向上查找, 直至到根). 只要没有被覆盖的话, 对象原型的属性就能在所有的实例中找到.原型默认为Object的新实例, 由于仍是对象, 故可以给该对象添加新的属性: // prototype默认为new Object(); 为了方便, 记为p_objfunction Person(name) { this.name name;}// 为 p_obj 增加 sayName 属性Person.prototype.sayName function(){ alert(this.name);}var john new Person(John); // john 的 base reference指向p_objvar eric new Person(Eric); // eric 的 base reference也是指向p_obj// 注意sayName代码中的this将指向实例化后的对象(this绑定)john.sayName(); // john对象本身没有sayName属性, 于是访问原型对象p_obj的sayName属性eric.sayName(); // 访问同一个原型对象p_obj的sayName属性var tmp Person.prototype;tmp.boss David;// 于这个运行点, p_obj已经被修改// 根据上述属性访问流程, 新的修改(boss属性)能反映到所有的实例, 包括已经创建和即将创建的alert(Johns boss is john.boss);alert(Erics boss is eric.boss);// hisCar和sayCar属性将增加到john对象而不是p_obj对象..john.hisCar Audi;john.sayCar function(){ alert(this.name has a car of this.hisCar);}john.sayCar();// ..因此下一句将错误, 因为eric对象本身和原型p_obj都没有sayName属性/* eric.sayCar(); */ 2.2 原型链除了能修改prototype指向的对象, 还能修改prototype指向哪一个对象, 即为prototype赋予一个不同的对象. 这可以实现一种简单的继承: function Superman() {}Superman.prototype.sayHello function(){ alert(Im a superman.);}function SupermanCan(skill){ this.skill skill;}// 为prototype赋予Superman的实例..SupermanCan.prototype new Superman();// ..再动态添加新的属性SupermanCan.prototype.sayMore function(){ this.sayHello(); // 调用父类的方法 alert(I can this.skill);}var david new SupermanCan(fly);// output: Im a superman. I can flydavid.sayMore(); 如果先实例化出一个对象, 再为构造函数prototype赋予一个不同的对象, 将会: 已经创建的对象的基引用不变, 将来创建的对象的基引用为新的原型对象: var f1 {echo: function() { alert(sound); } };function Foo() {};var foo new Foo(); // foo的基引用指向Object实例Foo.prototype f1;/* 未定义, 因为这是foo对象自己或者基引用指向的对象有echo属性吗? 而不是foo对象自己或者Foo.prototype指向的对象有echo属性吗? */alert(foo.echo);var foo2 new Foo(); // foo2的基引用指f1对象foo2.echo(); // output: sound 所有的构造函数的prototype都不能为空, 就是说Superman.prototype null 会被解释引擎无视; 另一方面, Object构造函数也有prototype属性(该属性是只读的, 可以为原型增加属性,但不能赋予不同的对象), 故因此可以有多层的原型链, 但原型链的根必定会是Object.prototype . 这意味着给Object.prototype增加属性影响到所有对象: Object.prototype.echo function() { alert(hello);}// echo属性将增加到所有对象固有对象和自定义对象var arr new Array();arr.echo();Array.echo();function ObjCons() { this.dummy d;}var obj new ObjCons();obj.echo();ObjCons.echo(); 3. 构造函数和new的实质构造函数是一个地地道道的函数, 一个函数之所以能成为构造函数, 是因为new运算符: this.msg window;function Test(){ alert(this.msg);}Test(); // windowvar test new Test(); // undefined. 因为test对象没有定义msg属性 二者区别在于如何切入对象: Test() 在某个对象(例子中为window)的上下文上执行代码, 即this指向这个对象; new Test()创建一个新对象, 并以这个新的对象为上下文(this指向新对象)执行代码, 然后返回这个新对象. 假如有个函数: function Test() { var dummy have money; this.wish dummy; doSomeThing(); } 结合以上的所有论述, 可以推测new Test()行为的伪代码表示为: 创建一个新对象temp; temp.constructor Test; temp.(base reference) Test.prototype; // 这一句先于代码体执行, 意味着构造函数里的this.xxx能访问原型对象的属性xxx bind: this temp; // 将this绑定到temp对象 // 开始执行函数代码 var dummy have money; this.wish dummy; // 为temp对象添加wish属性 doSomeThing(); .... // 结束执行函数代码 return temp;这个未必会符合内部的二进制实现, 但却能很好地解释了JavaScript的特性.