摘要:上一篇写了个工具函数$class,这篇再完善以下。实现以下功能1,继承2,子类继承父类时,不继承父类的私有属性/** * @param {String} className * @param {String/Function} superCls * @param {Function} classImp */function $class(className, superCls, classImp){ if(superCls === '') superCls = Object; function clazz(){ if(typeof this.init == "func
阅读全文
摘要:之前讨论过JavaScript中的写类方式。但没有讨论私有的实现。这篇看下。我们知道JS中私有属性的实现本质就是 var + closure。如下function Person(n, a){ // public this.name = n; // private var age = a; this.getName = function(){ return this.name; } this.getAge = function(){ return age; }}测试如下,age是私有的,使用点操作符无法获取到,而只能使用getName方法。var p = new Person('jack
阅读全文
摘要:我们很容易被漂亮的代码吸引,也不知不觉的在自己的代码库中加入这些。却没有冷静的想过它们的优劣。这不,我就收集了一系列形如 “是否为……?” 的判断的boolean函数。isNull: function(a){ return a === null;},isUndefined: function(a){ return a === undefined;},isNumber: function(a){ return typeof a === 'number';},isString: function(a){ return typeof a === 'string';},
阅读全文
摘要:我们知道标准鼠标有左,中,右三个键。鼠标按下时如何判断按下的是哪个键呢?W3C DOM-Level-2 定义如下W3C DOM 写道During mouse events caused by the depression or release of a mouse button, button is used to indicate which mouse button changed state. The values for button range from zero to indicate the left button of the mouse, one to indicate th
阅读全文
摘要:方法1function clone(obj){ var o; if(typeof obj == "object"){ if(obj === null){ o = null; }else{ if(obj instanceof Array){ o = []; for(var i = 0, len = obj.length; i < len; i++){ o.push(clone(obj[i])); } }else{ o = {}; for(var k in obj){ o[k] = clone(obj[k]); } } } }else{ o = obj; } return
阅读全文
摘要:方法链一般适合对一个对象进行连续操作(集中在一句代码)。一定程度上可以减少代码量,缺点是它占用了函数的返回值。一、对象链:方法体内返回对象实例自身(this)function ClassA(){ this.prop1 = null; this.prop2 = null; this.prop3 = null;}ClassA.prototype = { method1 : function(p1){ this.prop1 = p1; return this; }, method2 : function(p2){ this.prop2 = p2; return this; }, method...
阅读全文
摘要:最易读版function chain(obj){ function fun(){ if (arguments.length == 0){ return fun.obj; } var methodName = arguments[0], methodArgs = [].slice.call(arguments,1); fun.obj[methodName].apply(fun.obj,methodArgs); return fun; } fun.obj = obj; return fun;}易读版function chain(obj){ return function(){ va...
阅读全文
摘要:方式1,splicevar ary = [1,2,3,4];ary.splice(0,ary.length);console.log(ary); // 输出 [],空数组,即被清空了方式2,length赋值为0这种方式很有意思,其它语言如Java,其数组的length是只读的,不能被赋值。如int[] ary = {1,2,3,4};ary.length = 0;Java中会报错,编译通不过。而JS中则可以,且将数组清空了,var ary = [1,2,3,4];ary.length = 0;console.log(ary); // 输出 [],空数组,即被清空了目前 Prototype中数组
阅读全文
摘要:具名函数的各种调用方式 在之前篇幅中已经介绍过了。这篇看看如何判断一个函数是被new调用的,还是被其它方式调用的。方式1function Person(n,a){ this.name = n; this.age = a; if(this instanceof Person){ alert('new调用'); }else{ alert('函数调用'); }}var p = new Person('jack',30); // --> new调用Person(); // --> 函数调用方式2function Person(n,a){ th
阅读全文
摘要:很喜欢 蔡蔡 的这个标题,实际蔡蔡已经分析过了,这里借用了。或许有点标题党的意思。看完就知了。一、引子var a = {n:1};a.x = a = {n:2};alert(a.x); // --> undefined这是蔡蔡在看 jQuery源码 时发现这种写法的。以上第二句 a.x = a = {n:2} 是一个连续赋值表达式。这个连续赋值表达式在引擎内部究竟发生了什么?是如何解释的?二、猜想猜想1:从左到右赋值,a.x 先赋值为{n:2},但随后 a 赋值为 {n:2},即 a 被重写了,值为 {n:2},新的 a 没有 x属性,因此为undefined。步骤如下1, a.x =
阅读全文
摘要:如何给事件handler传参数?在刚刚接触Javascript的时候,由于对闭包理解不深刻,常常纠结于该问题。在讨论群里也经常碰到这样的问题,如下<!DOCTYPE HTML><html><head> <meta charset="utf-8"> <title>如何给事件handler传参数?</title></head><body> <a href="#" id="aa">Click me</a> <scri
阅读全文
摘要:所有Web前端同仁对 document.getElementById 都非常熟悉了。开发过程中经常需要用其获取页面id为xx的元素,自从元老级JS库Prototype流行后,都喜欢这么简写它// 方式1function $(id){ return document.getElementById(id); }有没有人想过为什么要这么写,而不用下面的方式写呢?// 方式2var $ = document.getElementById;这么写的$更简洁啊,也很明了,将document的方法getElementById赋值给变量$,用$去获取页面id为xx的元素。实际上方式2在IE6/7/8中是可行的
阅读全文
摘要:每个function有个prototype属性,称为原型。每个对象也有个原型,Firefox/Safari/Chrome/Opera 中可以通过__proto__来访问,IE6/7/8中没有提供相关接口。function Person(){ this.method1 = function(){}}Person.prototype.method2 = function(){}function Man(){}Man.prototype = new Person();Man.prototype.m1 = function(){}Man.prototype.m2 = function(){}var m
阅读全文
摘要:某知名互联网公司的一道JS笔试题:有函数a,b,c,c可能是在a或b内调用的,怎么知道?马上就想到了arguments.callee.caller,实际上有许多值得商榷的地方。如function a(){ c(); //()调用 //c.apply(null);//apply调用 //c.call...
阅读全文
摘要:Function.prototype的apply和call是在1999年发布的ECMA262 Edition3中才加入的(1998年发布ECMA262 Edition2)。在此前的的浏览器如IE5.01(JScript 5.0)中是没有apply和call的。因此会带来一些兼容性问题,以下是修复方式:if(!Function.prototype.apply){ Function.prototype.apply = function(obj, args){ obj = obj == undefined ? window : Object(obj);//obj可以是js基本类型 var i = 0
阅读全文
摘要:变量及变量声明是一门语言最基本的概念,初学者都会很快掌握。JavaScript中声明变量也是如此,很简单var(关键字)+变量名(标识符)。方式1var test;var test = 5;需注意的是该句不能包含在function内,否则是局部变量。这是第一种方式声明全局变量。方式2test = 5...
阅读全文
摘要:这里所说的JavaScript指浏览器环境中的包括宿主环境在内的。第一种是ECMAScript Global Object,第二种是宿主环境(Host)下的全局对象/函数。一、核心JavaScript内置对象,即ECMAScript实现提供的不依赖于宿主环境的对象这些对象在程序执行之前就已经(实例化)存在了。ECMAScript称为The Global Object,分为以下几种1, 值属性的全局对象(Value Properties of the Global Object)。有NaN,Infinity,undefined。2, 函数属性的全局对象(Function Properties o
阅读全文
摘要:如果把通过函数或方法调用,明确的将某种类型转换成另一种类型称为显示转换 ,相反则称为隐式类型转换 。google和维基百科中没有找到“显示类型转换”,“隐式类型转换”的字眼。暂且这么称呼。一、 运算中存在的隐式类型转换 1, “+”运算符var a = 11, b = '22';var c = a + b;这里引擎将会先把a变成字符串"11"再与b进行连接,变成了"1122"。有人会有疑问,为什么不把b变成数字22再进行算术加运算呢,这样的话c就是33了。没有为什么,当运算符“+”两边一个是数字类型,一个是字符串类型时,js引擎规定进行字
阅读全文
摘要:一道笔试题思考而来的,通常情况下没人会在函数内部修改参数值。这里仅拿出来讨论,有三种方式可以修改。1,直接修改函数声明时的形参function f1(a) { alert(a); a = 1;//修改形参a alert(1 === a); alert(1 === arguments[0]);}f1(10);函数f1定义了参数a,调用时传参数10,先弹出10,修改a为1,弹出两次true,a和arguments[0]都为1了。2,通过函数内部的arguments对象修改function f2(a) { alert(a); arguments[0] = 1;//修改arguments alert(
阅读全文
摘要:它们之间有区别吗?开发过程中似乎很少有人去加个额外的window,觉得多此一举。比如Ajax过程中回调函数解析JSON格式字符串...function callback(str){ var json = eval('(' + str + ')');}...通常直接使用eval,而非var json = window.eval('(' + str + ')');又比如调试时使用alert,很少有人使用window.alert;IE中获取事件对象使用event,很少有人使用window.event。(Firefox中在某些情况下也支持
阅读全文