这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
巧妙 1:函数 在 javascript 代码中函数是个不可多得的人才。 ♥ 它可以归置代码段,封装相对独立的功能。 ♥ 它也可以实现类,注入OOP思想。 jQuery 就是一个函数,你也可以把它当成类(呵呵,本身就是类)。
昨天写了篇通过 jQuery 源码学习 javascript(一),里面有一个定义对象 C 的方法,我早期也没有太注意这个方面的技术细节。后来我查了一下资料,发现里面有很多巧的地方。今天与大家分享
- (function(){
- var jQuery = function() {
- // 函数体
- }
- window.jQuery = window.$ = jQuery;
- })();
- console.log(jQuery);
上面的空函数就是所谓的构造函数,构造函数在面向对象语言中是类的一个基本方法。
巧妙 2:扩展原型何为原型对象?我给出一篇博文大家可以去了解一下 / article/16/0821/281205.html。 javascript 为所有函数绑定一个 prototype 属性,由这个属性指向一个原型对象。我们在原型对象中定义类的继承属性和方法等。 原型对象是 javascript 实现继承的基本机制。
- (function(){
- var jQuery = function() {
- // 函数体
- }
- jQuery.fn = jQuery.prototype = {
- // 扩展原型对象
- jquery: "1.8.3",
- test: function() {
- console.log('test');
- }
- }
- window.jQuery = window.$ = jQuery;
- })();
- (new jQuery()).test();
巧妙 3:使用工厂方法来创建一个实例 上面的方法必须使用下面的方法才能进行调用,这样就会产生很多对象,从而浪费内存消耗。 (new jQuery()).test(); jQuery 源码使用了很柔和的方法,也是大家比较熟悉的工厂方法,进行调用。
假想 1:让 jQuery 函数体直接返回该对象——我用 this
- (function(){
- var jQuery = function() {
- // 函数体
- return jQuery.fn.init();
- }
- jQuery.fn = jQuery.prototype = {
- // 扩展原型对象
- jquery: "1.8.3",
- init: function() {
- return this;
- },
- test: function() {
- console.log('test');
- }
- }
- window.jQuery = window.$ = jQuery;
- })();
- jQuery().test();
- (function(){
- var jQuery = function() {
- return this;
- }
- jQuery.fn = jQuery.prototype = {
- // 扩展原型对象
- jquery: "1.8.3",
- test: function() {
- console.log('test');
- }
- }
- window.jQuery = window.$ = jQuery;
- })();
- console.log(jQuery());
输出结果
发现这里的 this 指向 Window 对象。
假想 2:让 jQuery 函数体直接返回类的实例。
- (function(){
- var jQuery = function() {
- return new jQuery();
- }
- jQuery.fn = jQuery.prototype = {
- // 扩展原型对象
- jquery: "1.8.3",
- test: function() {
- console.log('test');
- }
- }
- window.jQuery = window.$ = jQuery;
- })();
- console.log(jQuery());
输出结果
发现上面是一个递归死循环,出现内存外溢。
巧妙 4:分隔作用域思考 1:init() 方法返回的 this 作用域是什么?
- (function(){
- var jQuery = function() {
- // 函数体
- return jQuery.fn.init();
- }
- jQuery.fn = jQuery.prototype = {
- // 扩展原型对象
- jquery: "1.8.3",
- init: function() {
- this.init_jquery = '2.0';
- return this;
- }
- }
- window.jQuery = window.$ = jQuery;
- })();
- console.log(jQuery().jquery);
- console.log(jQuery().init_jquery);
输出结果
init() 方法中的 this 作用域:this 关键字引用了 init() 函数作用域所在的对象,同时也能够访问上一级对象 jQuery.fn 对象的作用。——这种思路会破坏作用域的独立性,对于 jQuery 框架来说,很可能造成消极影响。 思考 2:怎么把 init() 中的 this 从 jQuery.fn 对象中分隔出来?——实例化 init 初始化类型。
- (function(){
- var jQuery = function() {
- // 函数体
- return new jQuery.fn.init();
- }
- jQuery.fn = jQuery.prototype = {
- // 扩展原型对象
- jquery: "1.8.3",
- init: function() {
- this.init_jquery = '2.0';
- return this;
- }
- }
- window.jQuery = window.$ = jQuery;
- })();
- console.log(jQuery().jquery);
- console.log(jQuery().init_jquery);
输出结果
通过实例化 init() 初始化类型,限定了 init() 方法里的 this,只在 init() 函数内活动,不让它超出范围。
巧妙 5:原型传递思考 1:在巧妙 4 中,我们把 init() 中的 this 从 jquery.fn 对象中分隔出来。那我们如何能做到保证" 巧妙 4"的基础上,还能访问 jQuery 原型对象呢?——原型传递。 让 jQuery 的原型对象覆盖 init() 构造器的原型对象。
- jQuery.fn.init.prototype = jQuery.fn;
全部代码:
- (function(){
- var jQuery = function() {
- // 函数体
- return new jQuery.fn.init();
- }
- jQuery.fn = jQuery.prototype = {
- // 扩展原型对象
- jquery: "1.8.3",
- init: function() {
- this.init_jquery = '2.0';
- return this;
- }
- }
- jQuery.fn.init.prototype = jQuery.fn;
- window.jQuery = window.$ = jQuery;
- })();
- console.log(jQuery().jquery);
- console.log(jQuery().init_jquery);
输出结果
妙棋把 init() 对象的 prototype 指针指向 jQuery.fn。——这样 init() 里的 this 继承了 jQuery.fn 原型对象定义的方法和属性。
总结感谢博友的留言,尤其是 puni ,给我介绍了一本不错的书。如果大家能补充一下,那就再好不过了。
来源: http://www.phperz.com/article/17/0418/281206.html