静态变量和函数、实例变量和函数以及prototype 说明

静态变量、函数

当定义一个函数后通过 “.”为其添加的属性和函数,通过对象本身仍然可以访问得到,但是其实例却访问不到,这样的变量和函数分别被称为静态变量和静态函数,用过Java、C#的同学很好理解静态的含义。

 1 function Obj(){
 2             }
 3
 4             Obj.a=0; //静态变量
 5
 6             Obj.fn=function(){ //静态函数
 7
 8             }
 9             console.log(Obj.a); //0
10             console.log(typeof Obj.fn); //function
11
12             var o=new Obj();
13             console.log(o.a); //undefined
14             console.log(typeof o.fn); //undefined

实例变量、函数

在面向对象编程中除了一些库函数我们还是希望在对象定义的时候同时定义一些属性和方法,实例化后可以访问,JavaScript也能做到这样。

 1 function Obj(){
 2                 this.a=[]; //实例变量
 3                 this.fn=function(){ //实例方法
 4
 5                 }
 6             }
 7
 8             console.log(typeof Obj.a); //undefined
 9             console.log(typeof Obj.fn); //undefined
10
11             var o=new Obj();
12             console.log(typeof o.a); //object
13             console.log(typeof o.fn); //function

这样可以达到上述目的,然而

 1 function Obj(){
 2                 this.a=[]; //实例变量
 3                 this.fn=function(){ //实例方法
 4
 5                 }
 6             }
 7
 8             var o1=new Obj();
 9             o1.a.push(1);
10             o1.fn={};
11             console.log(o1.a); //[1]
12             console.log(typeof o1.fn); //object
13             var o2=new Obj();
14             console.log(o2.a); //[]
15             console.log(typeof o2.fn); //function

上面的代码运行结果完全符合预期,但同时也说明一个问题,在o1中修改了a和fn,而在o2中没有改变,由于数组和函数都是对象,是引用类型,这就说明o1中的属性和方法与o2中的属性与方法虽然同名但却不是一个引用,而是对Obj对象定义的属性和方法的一个复制。

这个对属性来说没有什么问题,但是对于方法来说问题就很大了,因为方法都是在做完全一样的功能,但是却又两份复制,如果一个函数对象有上千和实例方法,那么它的每个实例都要保持一份上千个方法的复制,这显然是不科学的,这可肿么办呢,prototype应运而生。

prototype

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,默认情况下prototype属性会默认获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针,有些绕了啊,写代码、上图!

1 function Person(){
2
3             }

根据上图可以看出Person对象会自动获得prototyp属性,而prototype也是一个对象,会自动获得一个constructor属性,该属性正是指向Person对象。

当调用构造函数创建一个实例的时候,实例内部将包含一个内部指针(很多浏览器这个指针名字为__proto__)指向构造函数的prototype,这个连接存在于实例和构造函数的prototype之间,而不是实例与构造函数之间。

 1 function Person(name){
 2                 this.name=name;
 3             }
 4
 5             Person.prototype.printName=function(){
 6                 alert(this.name);
 7             }
 8
 9             var person1=new Person(‘Byron‘);
10             var person2=new Person(‘Frank‘);

Person的实例person1中包含了name属性,同时自动生成一个__proto__属性,该属性指向Person的prototype,可以访问到prototype内定义的printName方法,大概就是这个样子的

写段程序测试一下看看prototype内属性、方法是能够共享

 1 function Person(name){
 2                 this.name=name;
 3             }
 4
 5             Person.prototype.share=[];
 6
 7             Person.prototype.printName=function(){
 8                 alert(this.name);
 9             }
10
11             var person1=new Person(‘Byron‘);
12             var person2=new Person(‘Frank‘);
13
14             person1.share.push(1);
15             person2.share.push(2);
16             console.log(person2.share); //[1,2]

果不其然!实际上当代码读取某个对象的某个属性的时候,都会执行一遍搜索,目标是具有给定名字的属性,搜索首先从对象实例开始,如果在实例中找到该属性则返回,如果没有则查找prototype,如果还是没有找到则继续递归prototype的prototype对象,直到找到为止,如果递归到object仍然没有则返回错误。同样道理如果在实例中定义如prototype同名的属性或函数,则会覆盖prototype的属性或函数。

1 function Person(name){
2                 this.name=name;
3             }
4
5             Person.prototype.share=[];
6             var person=new Person(‘Byron‘);
7             person.share=0;
8
9             console.log(person.share); //0而不是prototype中的[]

构造简单对象

当然prototype不是专门为解决上面问题而定义的,但是却解决了上面问题。了解了这些知识就可以构建一个科学些的、复用率高的对象,如果希望实例对象的属性或函数则定义到prototype中,如果希望每个实例单独拥有的属性或方法则定义到this中,可以通过构造函数传递实例化参数。

1 function Person(name){
2                 this.name=name;
3             }
4
5             Person.prototype.share=[];
6
7             Person.prototype.printName=function(){
8                 alert(this.name);
9             }
时间: 2024-11-02 09:58:03

静态变量和函数、实例变量和函数以及prototype 说明的相关文章

Java中静态变量(类变量)、实例变量、局部变量和成员变量

导读 学习Java的过程中,一开始很容易被这些各种变量绕晕,这篇博客主要介绍了这几种变量之间的关系和区别. 例程 package com.cunyu.demo public class Demo { private String name; //成员变量.实例变量 private int age; //成员变量.实例变量 private int ID; //成员变量.实例变量 public static final String school = "卡塞尔学院"; //成员变量.静态变

JAVA中 成员变量和和实例变量区别

java语言支持的变量类型 类变量:独立于方法之外的变量,用 static 修饰. 局部变量:类的方法中的变量. 实例变量(全局变量):独立于方法之外的变量,不过没有 static 修饰. public class Variable{ static int allClicks=0; // 类变量 String str="hello world"; // 实例变量 public void method(){ int i =0; // 局部变量 }  } JAVA的局部变量 局部变量声明在

Java初始化顺序(静态变量、静态初始化块、实例变量、实例初始化块、构造方法)

1.执行顺序 1.1.一个类中的初始化顺序 (静态变量.静态初始化块)=>(变量.初始化块.构造器). 1.2.两个具有继承关系类的初始化顺序 父类的(静态变量.静态初始化块)=> 子类的(静态变量.静态初始化块)=> 父类的(变量.初始化块.构造器)=> 子类的(变量.初始化块.构造器). 示例如下:(结果见注释) 1 class A { 2 public A() { 3 System.out.println("Constructor A."); 4 } 5

java 中静态变量(类变量)与实例变量区别

静态变量: 在类内部中,方法的外部声明的对象而且加上static; 实例变量: 在类内部中,声明不需要加static; 比如: public class Demo{ int i1=0; static int i2=0; public void main(String[] args){ //报错,无法直接输出i1,实例对象 System.out.println(i1); //可以直接输出i2,静态变量 System.out.println(i2); Demo D1=new Demo(); Syst

Java变量类型,实例变量 与局部变量 静态变量

实例变量: 实例变量在类中声明,但在方法的外面,构造函数或任何块. 当空间分配给某个对象在堆中,插槽为每个实例变量创建值. 当一个对象与使用关键字 “new” 来创建,在对象被销毁销毁创建的实例变量. 实例变量认为必须由一个以上的方法,构造函数或块,或一个对象的状态的关键部分必须出现在整个类中引用的值. 实例变量可以在使用前或后级的级别声明. 访问修饰符可以给出实例变量. 实例变量对于所有方法,构造函数和块在类中可见.通常,建议,使这些变量私有(接入层).然而能见度子类可以给这些变量与使用访问修

实例变量,局部变量,全局变量,静态全局变量

摘抄网上的 定义: 实例变量:定义在一个类的各个内部方法之外,是内部方法共享的变量 局部变量:定义在方法之中的变量,但是这个方法使用的变量,其他方法和类没法使用. 全局变量:也称为外部变量,它是在函数外部定义的变量,一个程序的所有的java源文件都可用. 静态全局变量:一程序由多个java源文件组成时,可以用静态全局变量指定某一个java源文件,仅这个java文件可用这变量. 1 int a,b; //外部变量 2 static int c;//静态外部变量 3 4 public class S

java 成员变量、局部变量、静态变量、类变量、非静态变量、实例变量、向前引用、非法向前引用、静态代码块、非静态代码块

①java类的成员变量有俩种: 一种是被static关键字修饰的变量,叫类变量或者静态变量 另一种没有static修饰,为成员变量 ②通俗点说: 类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享.静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期. 而实例变量取决于类的实例.每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期. 注意点: 1.JAVA中初始化

成员变量(实例变量)&局部变量&静态变量(类变量)的区别

成员变量(实例变量)&局部变量区别: (1)作用域 成员变量:针对整个类有效. 局部变量:只在某个范围内有效.(一般指的就是方法,语句体内) (2)存储位置 成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中. 局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中. 当方法调用完,或者语句结束后,就自动释放. (3)初始值 成员变量:有默认初始值. 局部变量:没有默认初始值,使用前必须赋值. 成员变量(实例变量)&静态变量(类变量)区别: A:调用方式 静态变

Java 局部变量、实例变量、类变量(静态变量)区别

1. 局部变量: 局部变量是类的方法中的变量: 2. 实例变量: 实例变量也是类中独立于方法之外的变量,不过没有static修饰,也叫 对象变量 3. 类变量(静态变量): 类变量是类中独立于方法之外的变量,用static 修饰,也叫 静态变量 4. 伪代码说明 public class Variable{ static int allClicks=0;//类变量 String str="hello world";//实例变量 public void method(){ int i =

Java中的静态变量、实例变量和局部变量及其特征

变量类型 说明 特征 类变量(静态变量) 独立于方法之外的变量,用   static 修饰 类变量也称为静态变量,在类中以static关键字声明,但必须在方法构造方法和语句块之外.     无论一个类创建了多少个对象,类只拥有类变量的一份拷贝.     静态变量除了被声明为常量外很少使用.常量是指声明为public/private,final和static类型的变量.常量初始化后不可改变.     静态变量储存在静态存储区.经常被声明为常量,很少单独使用static声明变量.     静态变量在