Javascript
对象的创建
1.
var a=new Object();
a.x=1;a.y=2;
2.
var b={x:1,b,2}
3.
function Point (x,y){this.x=x;this.y=y}
var point=new Point(1,2);
javascript
中任何合法的函数都可以作为对象的构造函数。一旦函数作为构造函数执行,它内部的
this
属性将引用对象本身
。
构造函数通常没有返回值,它们只是初始化
this
传进来的对象(例如一个函数作为构造函数后,它内部的
this
属性引用了那个对象,如果对象有
x,y
等属性就可以通过
this.x this.y
来初始化它)。
构造函数有返回值的情况:
function test(){
this.name='test';
return 1;
}
function test1(){
this.name='test1';
return new String("test1");
}
var a=new test();
alert(a.name);//test
alert(a);//object
var b=new test1();//
alert(b.name);//undefined
alert(b);//test1
如果一个函数的返回类型为引用类型
(数组,对象或函数)的数据时当这个函数作为构造函数用
new
运算符执行构造时,构造函数体内的
this
值丢失,取而代之的是被返回的对象。
如果函数的返回值是一个值类型
,那么这个函数作为构造函数用
new
运算执行构造时,它的返回值将被舍弃。
new
表达式的结果仍然为
this
所引用的对象。
new foo()
的执行过程可以简单的理解为:
1.
创建一个新的对象实例,并继承foo.prototype
2. 将this绑定到这个新创建的对象上,new foo 跟new foo()是等价的在没有参数时
3.
这个构造函数返回的对象成了这个new表达式的结果。如果构造函数内没有返回对象,那么第一步中创建的对象将作为返回结果。more>>
对象的属性,方法:
对象的属性方法有四种类型
1.
私有类型
外界不可直接访问
2.
动态公有类型:外界可以访问,每个实例有一个副本,互相之间不影响。
3.
静态公有类型(原型类型):所有实例共象的一个副本
4.
类属性:类型而非对象的属性,没有构造函数时也可以直接访问
如下“
function Test(){
var x=0;// 私有属性
this.y=1;// 动态公有类型
}
var a=new Test();
Test.z=3; // 类属性
Test.prototype.w=20; // 静态公有类型
alert(a.z);//undefined
alert(Test.z);
alert(a.w);//20
a.w=40;
alert(a.w);//40 动态公有属性代替了原型类型
delete(a.w);
alert(a.w);//20
prototype:
javascript
中每个类型只有一个原型,默认情况下是一个
Object
对象
,但每一个实例可有多个类型,如:
function A(){}
A.prototype=new Object()// 可省略
A.prototype.w=10;
function B(){}
B.prototype=new A();//new A() 的过程:生成对象,将 new Object(),w 这些属性赋给这个对象,
//B 的 prototype 指向的对象中有了 new Object 和 w 这些属性 ……
function C(){}
C.prototype=new B();
var c=new C();
alert(typeof(c));//object
alert(c instanceof B);//true
alert(c instanceof A)//true
alert(c.w);
将一个属性添加为
prototype
的属性后这个属性为该类型的所有的对象所共享,而且这种共享是只读的,任何一个实例中只能通过同名的属性来覆盖它,但不能改变它。一个对象在查找某个属性时,先查找自身域的属性表,如果有则返回,如果没有,查找其
prototype
域,如果还没有则递归的查找
ptototype
所指对象的
prototype
域。
根据
new funciton
的执行过程和
prototype
的用法可以方便的创建大量副本
var p1=new Point(1,2);
var points=[];
var pointPrototype=function(){}
pointPrototype.prototype=p1;
for(var i=0;i<1000;i++){
points[i]=new pointPrototype();
}
对象的继承:
模拟:
1.
构造继承
function BaseObject(name){
this.getName=function(){return name}
}
function ChildObject(name){
BaseObject.call(this,name);// 这里的 this 指的是 ChildObject 的对象(设为 o ),因此调用 call 后, //BaseObjict 原来构造函数中的 this 就成了 o ,然后 o 就有了 getName 属性。
// 所以这里相当有了 this.getName=function(){return name} 这行代码
}
var c=new ChildObject('chen');
alert(c.getName());
但是这样不能继承父类型中的静态属性。
2.
原型继承法
function MyDate(){}
MyDate.prototype=new Date();
var date=new MyDate();
这样并不能调用
Date
的
toString
方法。也就是说核心对象不能被继承。
由于类的原型
(prototype)
实际上是一个
Object
的实例,它不能再次被实例化
(
它的初始化在脚本装载时已经执行完毕
)
。这么意思呢?我们知道在新建对象实例时,我们使用语句
new MyDate()
,这时我们可以看做
JavaScript
脚本引擎把
prototype
的一个浅拷贝作为
this
返回给类的实例
(
这里其实没有
发生拷贝,只是利用浅拷贝
这个概念来帮助理解
)
,如果类没有附加任何原型属性和原型方法,那么就等于返回了一个
new Object()
实例,如果
prototype
的原型属性类里有对象型的属性,那么就会造成共享对象实例的问题
(
类似于在传统
OOP
的类定义中使用了
static
修饰符来修饰了属性
)
如下面的实例。结果中
array
中的数组都打印的是
1,2,3,4
而
count
是不同的。这是因为数组是引用类型的而整数是值类型的。
<script>
function Collect(){
this.arr=[];
this.count=0;
}
function ArrayList(){
}
ArrayList.prototype=new Collect();
ArrayList.prototype.constructor=ArrayList;
// 为什么上面要把 ArrayList 赋值给新 prototype 的 constructor 呢?如果不做这个赋值, // 当我们从 ArrayList 的实例中, 通过 XXX.prototype.constructor 去取其构造函数,将会 // 获得 Collection 。这不是我们的本意,而且这是使用 instanceof 关键之比较对象实例和 // 对象也会出错。
var array=new ArrayList();
array.arr.push(1);
array.arr.push(2);
array.count=1;
var array2=new ArrayList();
array2.arr.push(3);
array2.arr.push(4);
array2.count=2
for(var i=0;i<array.arr.length;i++){
alert(array.arr[i]);
}
for(var i=0;i<array2.arr.length;i++){
alert(array2.arr[i]);
}
alert(array.count);
alert(array2.count);
</script>
3.
实例继承
function
MyDate(){ var instance =new Date(); instance.someFunction=..; return instance;
}
用闭包保证
this
不被修改:
function MyClass(){
var $this=this;
var foo=function(){
return $this.foo.apply($this,arguments);
}
}
利用闭包构造私有域
var a=0;var b=1;
(function(){
showAB=function(){
alert(a+" "+b);
}
var a=1;
var b=2;
alert(a);alert(b);
showAB();
})()
a=2;
b=5;
showAB();// 输出仍为 1,2
分享到:
相关推荐
JavaScript中的函数闭包是一个重要的概念,它涉及到函数的作用域、变量持久化以及内存管理等多个方面。闭包的本质是在函数内部创建另一个函数,使得内部函数能够访问并操作外部函数的局部变量,即使外部函数已经执行...
在讨论JavaScript编程语言时,匿名函数和闭包是两个重要的概念,它们在函数式编程和模块化代码设计中扮演着核心角色。匿名函数是没有具体名称的函数,它们可以是独立的,也可以是表达式的一部分,通常用于定义临时...
总结一下,JavaScript中的函数不仅是一种数据类型,还是实现面向对象编程的核心工具。通过原型链,我们可以实现基于原型的继承;通过闭包,我们能够控制作用域和访问变量,提升代码的复用性。理解和掌握这些概念,将...
闭包是ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在...而闭包工作机制的实现很大程度上有赖于标识符(或者说对象属性)解析过程中作用域的角色。
JavaScript函数闭包是模拟面向对象编程的一种技术,它允许函数记住并访问其词法作用域,即使在函数执行完毕后也能保持对其的访问。这种特性使得JavaScript能够在没有内置类和继承等传统面向对象特性的情况下实现类似...
闭包是JavaScript中的一个核心概念,它是指有权访问另一个函数作用域中变量的函数。闭包的产生是因为内部函数持有了外部函数的变量,即使外部函数已经执行完毕,内部函数仍然可以访问这些变量。 #### 三、闭包的...
JavaScript中的函数对象调用模式是编程中至关重要的概念,它涉及到函数作为一等公民、作用域、闭包、原型链等多个核心知识点。这篇博客通过深入分析JavaScript中的函数调用模式,帮助开发者更好地理解和掌握这些概念...
在JavaScript中,匿名函数、函数直接量和闭包是三种非常重要的概念,它们在编程实践中有着广泛的应用。让我们逐一深入探讨这些概念。 1. **匿名函数**: 匿名函数是指没有名字的函数,通常作为表达式的一部分存在...
在JavaScript中,闭包(Closure)是一个极其关键的概念,它使得内部函数能够访问到其外部函数的作用域内的变量,即使外部函数已经执行完毕。这一特性是基于JavaScript的函数作用域规则以及函数本身可以作为值进行...
**匿名函数**和**闭包**都是JavaScript中非常强大的特性。通过灵活运用这些概念,可以编写出更加高效和可维护的代码。然而,需要注意的是,由于闭包会导致函数的作用域被持续保留,因此过度使用闭包可能会导致内存...
这表明了JavaScript函数的灵活性和对象的特性。在JavaScript中,函数、数组、对象等都是对象,它们可以包含各种属性,甚至可以动态地修改自己的结构。 原型(Prototype)是JavaScript实现继承的基础,每一个对象都...
在JavaScript函数式编程中,闭包是一个非常重要的概念。闭包是指有权访问另一个函数作用域中变量的函数。由于JavaScript的作用域链,闭包能够访问到函数定义时的外部变量,即使外部函数已经执行结束。闭包通常用于...
本文提供了基于闭包的JavaScript面向对象编程框架的设计和实现,展示了闭包在JavaScript中实现基于类的面向对象编程的可能性。 知识点: 1. 闭包(Closure)是一种JavaScript编程技术,用于实现基于类的面向对象...
在闭包中,`this`的指向取决于调用上下文。在上述的`getUserFunction`示例中,`this`在闭包内指向的是`window`,而不是`obj`,因为闭包不是一个对象的方法。如果想让`this`指向`obj`,可以使用`.call`或`.apply`方法...
在JavaScript中,当一个函数作为另一个函数的返回值时,这个内部函数就具有了访问外部函数作用域的闭包能力。例如,在提供的代码`function makeFunc(x){ return function(){return x++;}}`中,`makeFunc`返回的匿名...
第二个例子通过立即执行函数表达式(IIFE)来解决这一问题,确保每个函数闭包都能正确地访问到各自的循环变量。 闭包是JavaScript编程中的一个重要特性,它提供了创建私有变量、管理作用域和记忆化等强大功能,使得...