- 浏览: 1163782 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
zhizhen23:
LZ 提供的链接地址失效了
重写的isPlainObject方法 -
LovingBaby:
LovingBaby 写道function fun() {}f ...
读jq之二(两种扩展) -
LovingBaby:
说的很清楚!jQuery作者为了实现简洁调用的苦心!高超的编程 ...
读jq之一(jq对象的组成) -
hard_ly:
...
将伪数组转换成数组 -
zlxzlxzlxzlxzlx:
这不能算是任意进制之间的转换,例如二十六进制、十二进制又该如何 ...
用递归实现十进制数转换N进制
JQ中发现的,jQuery.Event类。估计作者是为了减少代码量。定义一个类,但不用new关键字去创建该类对象,而使用方法调用()方式去创建该对象。
多数时候我们是这样写类,然后使用new创建对象的。
function Person(name,age){ this.name=name; this.age=age; } Person.prototype={ setName : function(n){this.name=n;}, getName : function(){return this.name;} } var p = new Person('jack',25);
改成这样的
function Person(name,age){ //条件改为(this==window)或(this==self)或(this.constructor!=Object) if(!this.setName){ return new Person(name,age); } this.name=name; this.age=age; } Person.prototype={ setName : function(n){this.name=n;}, getName : function(){return this.name;} } var p = Person('jack',25);
注意该类较最上面的写类方式中多了以下
if(!this.setName){ return new Person(name,age); }
好,创建类的实例(对象)方式也变成了如下:
var p = Person('jack',25);
这种创建方式(函数调用)较上面的少了“new_”,new和空格,实际上是在类内部new了。而这样方式每次创建对象可以减少4个byte。
如果把类内部的if判断条件换成非prototype上的属性,如this.name。程序会提示出错:too much recursion
function Person(name,age){ if(!this.name){ return new Person(name,age); } this.name=name; this.age=age; } Person.prototype={ setName : function(n){this.name=n;}, getName : function(){return this.name;} } var p = Person('jack',25);
评论
15 楼
xing_kenny
2013-01-16
if(!this.setName){
为什么不直接使用
if( !(this instanceof Person)) ?
为什么不直接使用
if( !(this instanceof Person)) ?
14 楼
lgzjw
2010-04-11
外表看来少了4byte的也就是new 少了,并且window下also不能有if判断的同名对象存在.
13 楼
weiqingfei
2010-04-09
zhouyrt 写道
weiqingfei 写道
zhouyrt 写道
weiqingfei 写道
直接调用Person方法时,这儿的this指的是window,只有在new Person的时候,this才指的是Person的一个实例,原本这儿就是为了判断是直接调用,还是在new。但是当window里也有这个方法或者属性的时候,就失效了。
说的有道理。
把条件改成以下就可以了,不怕同名的全局函数了。
1,this==window
2,this===window
3,this==self
4,this!=Object
有时候,这个方法的声明,不一定会放在全局(也就是window)上,所以我觉得如果是内部使用的话也就算了,开放给用户用的话不大合适。
诚如jq中jQuery.Event的定义,Event不是全局的而是挂在jQuery上的,这样定义的用!this.preventDefault判断没有问题。或者说即使定义了全局的preventDefault(函数/变量),这个条件也不会失效的。因为jQuery.Event类中的this指向的是jQuery而非window。
因此,这种写法有几个前提。
1,是在定义一个类
2,用new去创建这个类的实例
3,追求极致的精简代码
嗯,其实是一样的,要保证object jQuery里面没有属性或者方法preventDefault,否则也同样会失效。
但是用户使用jQuery.extend是可以添加这个方法或者属性的。
我没用过jQuery,只是刚开始看它的代码,还不知道jQuery.Event到底怎么用,如果可以开放给用户的话,这个地方就要注意了。
12 楼
蔡华江
2010-04-09
zhouyrt 写道
蔡华江 写道
还有一个问题就是,这种写法会带来call与apply方法的不正确运行
可以运行,只要正确的传了上下文参数。但这样违背了每次创建对象减少byte的初衷。
以下的p0,p1,p2分别是(),call,apply调用,会发现call,apply创建对象的代码比new还多。
function setName(){}; function Person(name,age){ if(this==window){//this==self or this.constructor != Object return new Person(name,age); } this.name=name; this.age=age; } Person.prototype.setName = function(n){this.name=n;}; Person.prototype.getName = function(){return this.name;} var p0 = Person('jack',25); var p1 = Person.call(window,'jack',25); var p2 = Person.apply(window,['jack',25]);
是不是我要这样认为,你在楼上举的特例是能正常运行的。
可是我调用call与apply时,通常不是放置window作为scope的,如果是那样的话,我直接使用window就行了。
也许我会使用一个Student类来调用,if(this==window)的验证岂不是无效的。
11 楼
zhouyrt
2010-04-09
蔡华江 写道
还有一个问题就是,这种写法会带来call与apply方法的不正确运行
可以运行,只要正确的传了上下文参数。但这样违背了每次创建对象减少byte的初衷。
以下的p0,p1,p2分别是(),call,apply调用,会发现call,apply创建对象的代码比new还多。
function setName(){}; function Person(name,age){ if(this==window){//this==self or this.constructor != Object return new Person(name,age); } this.name=name; this.age=age; } Person.prototype.setName = function(n){this.name=n;}; Person.prototype.getName = function(){return this.name;} var p0 = Person('jack',25); var p1 = Person.call(window,'jack',25); var p2 = Person.apply(window,['jack',25]);
10 楼
zhouyrt
2010-04-09
weiqingfei 写道
zhouyrt 写道
weiqingfei 写道
直接调用Person方法时,这儿的this指的是window,只有在new Person的时候,this才指的是Person的一个实例,原本这儿就是为了判断是直接调用,还是在new。但是当window里也有这个方法或者属性的时候,就失效了。
说的有道理。
把条件改成以下就可以了,不怕同名的全局函数了。
1,this==window
2,this===window
3,this==self
4,this!=Object
有时候,这个方法的声明,不一定会放在全局(也就是window)上,所以我觉得如果是内部使用的话也就算了,开放给用户用的话不大合适。
诚如jq中jQuery.Event的定义,Event不是全局的而是挂在jQuery上的,这样定义的用!this.preventDefault判断没有问题。或者说即使定义了全局的preventDefault(函数/变量),这个条件也不会失效的。因为jQuery.Event类中的this指向的是jQuery而非window。
因此,这种写法有几个前提。
1,是在定义一个类
2,用new去创建这个类的实例
3,追求极致的精简代码
9 楼
蔡华江
2010-04-09
还有一个问题就是,这种写法会带来call与apply方法的不正确运行
8 楼
aninfeel
2010-04-09
没意义,还会是代码的可读性变差。
7 楼
weiqingfei
2010-04-09
zhouyrt 写道
weiqingfei 写道
直接调用Person方法时,这儿的this指的是window,只有在new Person的时候,this才指的是Person的一个实例,原本这儿就是为了判断是直接调用,还是在new。但是当window里也有这个方法或者属性的时候,就失效了。
说的有道理。
把条件改成以下就可以了,不怕同名的全局函数了。
1,this==window
2,this===window
3,this==self
4,this!=Object
有时候,这个方法的声明,不一定会放在全局(也就是window)上,所以我觉得如果是内部使用的话也就算了,开放给用户用的话不大合适。
6 楼
蔡华江
2010-04-09
个人感觉,这个会导致思路上混乱。
5 楼
zhouyrt
2010-04-09
weiqingfei 写道
直接调用Person方法时,这儿的this指的是window,只有在new Person的时候,this才指的是Person的一个实例,原本这儿就是为了判断是直接调用,还是在new。但是当window里也有这个方法或者属性的时候,就失效了。
说的有道理。
把条件改成以下就可以了,不怕同名的全局函数了。
1,this==window
2,this===window
3,this==self
4,this!=Object
4 楼
weiqingfei
2010-04-08
直接调用Person方法时,这儿的this指的是window,只有在new Person的时候,this才指的是Person的一个实例,原本这儿就是为了判断是直接调用,还是在new。但是当window里也有这个方法或者属性的时候,就失效了。
3 楼
zhouyrt
2010-04-08
weiqingfei 写道
这个判断有缺陷
如果全局有个setName属性或者方法,这个判断就会失效。
if(!this.setName){ return new Person(name,age); }
如果全局有个setName属性或者方法,这个判断就会失效。
感谢提醒,但这是为什么呢?即使加了一次闭包仍然失效。
2 楼
weiqingfei
2010-04-08
这个判断有缺陷
如果全局有个setName属性或者方法,这个判断就会失效。
if(!this.setName){ return new Person(name,age); }
如果全局有个setName属性或者方法,这个判断就会失效。
1 楼
lixinlixin2008
2010-04-07
呵呵,学到了,省的字节虽然少,不过对于追求极致的人来说,还是有用的,对prototype的执行顺序真是理解深刻...
发表评论
-
JavaScript获取图片的原始尺寸
2016-04-20 10:30 1597页面里的img元素,想要 ... -
JavaScript中奇葩的假值
2016-03-14 17:43 1161通常在以下语句结构中需要判断真假 if分支语句 whi ... -
世界上最短的数字判断代码
2016-03-14 16:21 1584我们知道JavaScript提供了typeof运算符,因此最 ... -
getBoundingClientRect在IE9/10里的bug
2015-01-12 08:30 1654getBoundingClientRect可以获得页面中某个 ... -
JavaScript中的直接量与初始器的区别
2014-11-08 06:09 1631很多代码优化及公司规范都会提到 写对象不应该 var ... -
JavaScript中的不可见数据类型
2014-11-02 11:08 1294JS提供了一些内置对象、函数和构造器供我们编程,如Math ... -
ES5严格模式
2014-10-08 18:20 1256严格模式(Strict mode)是由ECMA-262规范 ... -
JavaScript生成GUID的算法
2014-07-16 14:25 3014全局唯一标识符(GUID,Globally Unique ... -
JavaScript中点号“.”的多义性
2014-06-07 19:42 1658点号「.」在JavaScript中 ... -
冗余换性能-从Backbone的triggerEvents说开了去
2014-02-19 11:03 953Backbone是一个优秀的前端MVC库,它的代码质量必定 ... -
JavaScript中delete操作符不能删除的对象
2013-11-27 13:21 1309ES3 中,delete在8.6.2.5及11.4.1有介 ... -
JavaScript中instanceof对于不同的构造器可能都返回true
2013-11-19 11:13 1214我们知道 instanceof 运算符用来检查对象是否为某 ... -
JavaScript里模拟sleep
2013-10-16 07:52 1547有几种方式,但都不完美 一、不断循环,直到达到指定时间 ... -
参数有中包含空格且使用Post提交时须将空格转换成加号
2013-10-14 08:07 5208jQuery的serialize模块中有个r20正则 ... -
JavaScript中“基本类型”之争
2013-10-04 20:58 1125前端面试中常被问到的问题之一就是“JavaScript的基本 ... -
ES3和ES5关于计算顺序的问题(ES5先计算函数ES3则是参数)
2013-09-13 23:35 1313从cmc那看到的,分享给园友。以下是一个怪异的代码,谁 ... -
一道关于"/g"笔试题
2013-07-26 07:13 1056正则里“g”表示全局(global)的意思,比如当替换字符串 ... -
JavaScript原型继承的陷阱
2013-05-27 20:51 1397JavaScript默认采用原型 ... -
JavaScript中__proto__与prototype的关系
2013-05-21 10:38 1459这里讨论下对象的内 ... -
JavaScript中__proto__与prototype的关系
2013-05-21 10:01 3这里讨论下对象的内 ...
相关推荐
虽然我们在代码中没有显式使用`new`关键字来创建对象,但实际上ATL会在内部调用`new`来分配内存。对象工厂通过调用`CComObject<T>::CreateInstance`来创建对象,这实际上会触发C++的`new`操作符。 **4.3 初始化** ...
JavaScript提供了多种创建对象的方法,包括字面量语法、构造函数、对象原型、工厂函数、模块模式以及近年来引入的类(Class)语法。这篇博客将深入探讨这些方法,帮助你更好地理解和掌握JavaScript中的对象创建。 ...
这是最简单直接的创建对象的方式,通过大括号{}来定义一个对象,然后在内部用逗号分隔各个属性和方法。 ```javascript var obj = { name: 'Alice', age: 25, sayHello: function() { console.log('Hello!'); ...
这时,我们需要使用`dlopen`(Unix-like系统)或`LoadLibrary`(Windows)这样的函数,以及相应的函数指针绑定方法来根据字符串创建对象。 - **元类或元对象协议**:在某些框架(如Qt)中,存在元类系统,可以解析...
- **工厂方法**:通过工厂类来创建对象,可以隐藏对象创建的细节,提高代码的可维护性。 - **依赖注入**:框架如Spring提供依赖注入功能,可以通过配置文件或注解将依赖关系注入到对象中,简化对象的创建和管理。 ...
7. **接口实现**:在某些情况下,可以使用接口来隐藏构造函数,从而实现只创建对象不调用构造函数。但是,接口不能包含实例构造函数,因此这种方法实际上涉及的是设计模式和具体实现策略的选择。 总结起来,C#提供...
以下是一个简单的示例,展示了如何使用隐藏API来解析一个APK文件并获取相关信息: ```java // 定义APK文件路径 String apkPath = "/sdcard/qq.apk"; // 创建PackageParser对象 PackageParser packageParser = new ...
C#的New关键字的几种用法 C#语言中的New关键字是一个多...C#语言中的New关键字是一个非常有用的工具,它可以用于创建对象、隐藏基类成员和约束泛型参数的类型。了解New关键字的多种用法,将有助于你更好地编写C#代码。
### JavaScript工厂模式与构造函数模式创建对象方法解析 #### 一、工厂模式 在JavaScript中,工厂模式是一种常用的设计模式,用于封装创建对象的过程。它通过一个函数来创建具有相似特性的多个对象实例,这些对象...
### Java零基础-对象的创建和使用-内存分析 #### 知识点一:对象的创建 在Java中,对象的创建是通过`new`关键字完成的。对象创建的两个主要步骤包括分配内存和初始化对象。 1. **分配内存**:当使用`new`关键字时...
1. **创建对象**:在`Main`类中,创建一个`Person`对象。 2. **设置属性值**:使用`setName`方法为`Person`对象的`name`属性设置一个具体值。 3. **调用方法**:调用`sayHello`方法展示对象的行为。 示例代码: ```...
此外,如果你是在非VBA的环境中,比如C#或VB.NET,你同样可以使用.NET Framework中的 `Microsoft.Office.Interop.Excel` 命名空间来创建Excel COM对象并进行同样的操作: ```csharp using Microsoft.Office.Interop...
在本课件"面向对象技术课件-New"中,我们可以深入探讨这一主题。 1. **面向对象的基本概念**:面向对象技术的核心思想包括类、对象、继承、封装和多态。类是对象的模板,定义了对象的属性和行为;对象是类的实例,...
在创建和使用类时,我们首先定义类,然后通过实例化来创建类的个体实例。接下来,我们将深入探讨如何在PHP中创建类和实例化对象,以解答"创建矩形类Rectangle并实例化r1对象"的课后习题。 1. **创建类**: 在PHP中...
我们使用`new`关键字来调用构造函数并创建一个新的对象实例。例如: ```javascript function Person(name) { this.name = name; } var person1 = new Person('Alice'); ``` 这里的`Person`就是构造函数,`person...
我们通过调用类的构造方法来创建对象,并使用`new`关键字分配内存空间。 ```java Car myCar = new Car("Toyota", 2020); myCar.drive(); // 输出 "Driving the Toyota car made in 2020" ``` 在Java中,类还可以...
* 构造函数:构造函数是一种特殊的方法,它具有和它所在的类完全一样的名字,一旦定义好一个构造函数,创建对象时就会自动调用它。 * 类成员:类成员包括成员变量和成员方法,成员变量用于存储对象的状态,成员方法...
当我们创建一个子类对象并将其赋值给父类引用时,这种行为被称为向上转型(Upcasting)。这一过程是自动且安全的,因为子类对象包含了父类的所有属性和方法。下面我们将深入探讨这个主题,包括它的原理、示例代码...