簡體   English   中英

javascript方法鏈接和this對象

[英]javascript method chaining and the this object

給定一個鏈式函數,聲明如下:

Something.prototype.method1.method2 = function(){
    return this === Something.prototype.method1; // true
}

如何(如果可能)可以訪問調用實例對象?

instance.method1.method2() // access to instance and method1?

如果您真的想濫用JS,請忽略我的回答。

否則,讓我展示一下鏈接功能的概念。 原型函數可以互相使用,因為它們總是返回this指針。 因此鏈中的下一個函數將在同一對象上調用:

Animal = function Animal(name) {
  this.food = 0;
  this.name = name;

  return this;
}

Animal.prototype.eat = function eat() {
  this.food--;

  return this; 
}

Animal.prototype.hunt = function hunt() {
  this.food++;

  return this;
}

現在,您可以執行以下操作:

// Lets create Jack the cat.
var cat = new Animal('Jack');

// Let him hunt and eat with some chained function calls.
cat.hunt().hunt().eat();

// Check how much food does Jack got.
console.log(cat.food) // => 1

// Some explanation about this return values.
var anotherPointerOnCat = cat.hunt();

console.log(anotherPointerOnCat === cat) // => true
// True because they point on the same object in memory.

// So I can call the chained functions on that as well.
anotherPointerOnCat.eat().eat();

您需要在構造期間定義它:

function Thing() {
  var _t = this;

  this.method1 = function() {
    console.log('method1', _t);
  }

  this.method1.method2 = function() {
    console.log('method1.method2', _t);
  }
}

在Chrome控制台中工作:

var t1 = new Thing();
t1.a = 1;
t1.method1();
t1.method1.method2();

var t2 = new Thing();
t2.b = 2;
t2.method1();
t2.method1.method2();

產量:

method1 "Thing {method1: function, a: 1}"
method1.method2 "Thing {method1: function, a: 1}"
method1 "Thing {method1: function, b: 2}"
method1.method2 "Thing {method1: function, b: 2}"
Something.prototype.method1.method2 = function(){
    return this === Something.prototype.method1; // true
}

您聲稱此函數將始終返回true。 但是這是錯誤的。 一個例子:

var jsIsFun = Something.prototype.method1.method2;
jsIsFun(); //false
jsIsFun.call(Something.prototype.method1); //true

這是因為this關鍵字綁定在函數執行上。 但是,使用call()方法,我們可以更改與this綁定的對象。

發生這種情況是因為函數的上下文是在執行時應用的。

但是,您希望不直接在對象/函數中訪問變量。

我們也有一個詞:范圍。

而且您遇到的問題是不了解Scope及其在JS中的工作方式。

您可以將對象設置為鏈對象,即設置該對象,使其采用可以作為父對象的參數,並使其返回具有相同鏈的其他對象。

偷@burninggramma的示例:

function buildChain(parent, method){
   var child = {};
   child.prototype = parent;
   child.parentage = function(){
     var chain = [];
     if (child.prototype.parentage) {
       chain = child.prototype.parentage();
     }
     chain.push({obj:this, method:method});
     return chain;
   }
}

function Animal(name){
  this.food = 0;
  this.name = name;

  return this;
}

Animal.prototype.eat = function eat() {
  this.food--;

  return buildChain(this, this.eat); 
}

Animal.prototype.hunt = function hunt() {
  this.food++;

  return buildChain(this, this.hunt);
}

並使用:

var cat = new Animal('Tom');
var mouse = new Animal('Jerry');

cat.hunt().hunt().eat().parentage(); // [{obj: cat, method: hunt}, {obj: chain1, method: hunt}, {obj: chain2, method: eat}]
mouse.eat().eat().parentage(); // [{obj: mouse, method: eat}, {obj: chain1, method: eat}]

var chainer = cat.hunt().eat();
chainer.parentage(); // [{obj: cat, method: hunt}, {obj: chain1, method: eat}]
chainer.hunt().parentage(); // [{obj: cat, method: hunt}, {obj: chain1, method: eat}, {obj: chain2, method: hunt}]
chainer.eat().parentage(); // [{obj: cat, method: hunt}, {obj: chain1, method: eat}, {obj: chain2, method: eat}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM