静态方法和实例方法的区别?

如题详述: 不知道改怎么区分这两种方法,它可能会涉及到对象的定义方式,所以问题有二

问题1: 定义方式

var str = new String('luo');

var str = 'luo'

这两种定义字符串的方式有什么区别?

问题二: 方法的调用产生的‘静态方法’和‘实例方法’

var str = 'luo';
console.log(str.toLowerCase());    //LUO

这是实例方法,通过原型链继承的,好理解

但是,并不是所有方法都是原型链继承的,如下:

console.log(String.fromCharCode(76,85,79));    //LUO

为什么会有这样的方法?这个方法是怎么理解?

阅读 8.7k
5 个回答

1.var str = 'luo'这个方式定义的是一个原始类型的string,
var str = new String('luo');这种方式是以String为构造函数定义了一个新的对象。
比较相似的还有var str = String('luo');这个也是定义的原始类型的string。
以上的String指的是js的一个转化参数为字符串的函数。

以下的String指的是js的一个全局自有对象。
2.例子中的fromCharCode就是String的静态方法,也就是直接可以通过String调用的方法,不需要在一个String的实例上调用。
实例方法就是实例化后对象的方法,每个实例都会有这个方法,可以被继承。

问题一:

var str = new String('luo') // 数据类型是object
var str = 'luo' // 数据类型是string
                                  +--------------+
                                  |              |
                                  |  String      |
                                  |              | <-----------------------------------+
      +-------------+             |  .fromCharCode                                     |
      |             |             |              |                                     |
      | Function    |             |  .toLocaleString                                   |
      |             |             |              |                                     |
+---> |  ......     |             |   ......     |                +----------------+   |
|     |             |             |              |                |  Prototype     |   |
|     |             |             |  .prototype+----------------->+                |   |
|     |  .prototype |             |              |                |  .toLowerCase  |   |
|     |      +      |       +------+ .__proto__  |                |                |   |
|     |      |      |       |     +--------------+                |  .concat       |   |
|     |      |      |       |                                     |                |   |
|     +-------------+       |                                     |  .constructor +----+
|            |              |                                     |                |
|            |              |     +--------------+                |  ......        |
|            |              |     |              |                |                |
|            |              |     |  'luo'       |                +------+---------+
|            v              |     |              |                       ^
|    +-------+-------+      |     |  .__proto__+-------------------------+
|    |               | <----+     |              |
|    |  Prototype    |            |  ......      |
|    |               |            |              |
|    |  .call +---------------->  |              |
|    |               |            |              |
+------+.constructor |            |              |
     +---------------+            +--------------+

问题1,

var literal = 'hello';
literal.prop = 'xyz';
 
var copy = literal;
 
console.log(copy.prop)
-> undefined
var obj = new String('hello');
obj.prop = 'xyz';
 
var copy = obj;
console.log(copy.prop);
-> 'xyz'

参考链接:https://codeutopia.net/blog/2...
问题2:
你需要了解原型链,对象通过.调用方法,是有顺序的,比如

const Person = function() {
    this.getName = function(){ return 'aaa' }// 这里就是实例方法
}
Person.prototype.getName = function() { return 'bbb'; } // 这里是原型上的方法
const peter = new Person();
console.log(peter.getName()); // 'aaa'

这段代码可以看到,当调用一个对象的某个方法时,首先对象会查找本身有没有设置这个属性,如果找不到的话,其实每个对象都有一个__proto__属性,指向创建这个对象的构造函数的原型(这里也就是Person.prototype),原型也就是一个对象,也有自己的属性和__proto__,如果原型还找不到,就这样沿着__proto__一直找下去,这就构成了js的原型链。实例方法是每个对象都有一份的。
静态方法就是直接在构造函数上定义方法:

Person.toSmall = function() {
    return 'person';
}

静态方法和实例方法没什么关系。

class X{

static sayA(){//static method
     console.log("a")
}
sayB(){//instance method
     console.log("b")
}

}

const x = new X();
x.sayA(); // error
x.sayB(); //b

X.sayA(); //a
X.sayB(); //error

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题