2017-03-05 58 views
0

對於任何未知數量的對象,如果需要,我想截取和更改某些屬性。我已經嘗試過getter和setters,但是我只能靠近我想要的,只能用於已知對象。如何截取和修改任何對象的特定屬性

下面是什麼,我想實現的例子:我的範圍/關閉

之外創建

對象正如你可以看到這些是無法從外部訪問的對象,我想什麼要做的是檢查每個year_of_birth屬性,並在創建或修改任何未知對象時對其進行修改。我得到的最接近的是getters/setters,但是我必須傳遞這個對象,並且每當它改變它的值時它就會自行循環。

試圖通過檢查年齡本年度糾正year_of_birth一個例子

Object.defineProperty(unknown_object, 'year_of_birth', { 
    set: function(year) { 
     if (this.age && 2017 - this.age > year) { 
      this.year_of_birth = 2017 - this.age; 
     } 
    } 
}); 

Object.defineProperty(unknown_object, 'year_of_birth', { 
    get: function(year) { 
     if (this.age && 2017 - this.age > year) { 
      return 2017 - this.age; 
     } 
    } 
}); 

,但仍然沒有工作,只與我有奇異對象工作直接訪問。

有沒有辦法做到這一點?請不要使用像jQuery這樣的庫/框架解決方案。

編輯:代碼段的例子,因爲上面還不夠清楚:

// Here I define some sort of solution to manipulate any object property of name "year_of_birth" 
 

 
// unknown_object or a sort of prototype/constructor that intercepts any object, regardless of its scope 
 

 
Object.defineProperty(unknown_object, 'year_of_birth', { 
 
    set: function(year) { 
 
     if (this.age && 2017 - this.age > year) { 
 
      this.year_of_birth = 2017 - this.age; 
 
     } 
 
    } 
 
}); 
 

 
// or 
 

 
Object.defineProperty(unknown_object, 'year_of_birth', { 
 
    get: function(year) { 
 
     if (this.age && 2017 - this.age > year) { 
 
      return 2017 - this.age; 
 
     } 
 
    } 
 
}); 
 

 

 
// I want to modify "year_of_birth" or any other object property that is inside the below scope 
 
// I do not have access to that scope, I cannot modify the function to allow access to its scope, I cannot do anything to it besides trying to modify the objects from the outside through some method that I am trying to find out in this question 
 

 
(function() { 
 
    var john = { 
 
     age: 28, 
 
     year_of_birth: 1985 
 
    }; 
 
    var anne = { 
 
     age: 31, 
 
     year_of_birth: 1985 
 
    }; 
 
}()); 
 

 
// Whenever a "year_of_birth" object property is read/set it should change to whichever value it has been established in the setters/getters at the top

+0

你有你的對象的句柄?你是否控制了誰在你的代碼中引用了它? –

+0

@MadaraUchiha正如我所解釋的,我打算爲任何數量的我無法直接訪問的對象執行此操作。我提供的例子展示瞭如何在一個自我封閉的匿名函數中產生這些對象,我無法操縱它的內容或將它們暴露給外部作用域。 – Shadow

+0

你想要什麼是不可能的。 –

回答

0

在多次被告知我所問的內容不可行之後,我發現了一種通過定位Object.prototype來實現此目的的方法。

解決方案如下,「my_property」是我希望定位的任何對象屬性名稱。

Object.defineProperty(Object.prototype, "my_property", { 
 
    set: function (value) { 
 
     this._value = value; 
 
    }, 
 
    get: function() { 
 
     return "changed"; 
 
    } 
 
}); 
 

 
var some_object = {}; 
 

 
some_object.my_property = "unchanged"; 
 

 

 
document.body.innerHTML += some_object.my_property;
My property value is:

0

您可以使用RegExp解析原<script>.textContent獲得分配給變量標識符變量標識符和對象。操作對象以滿足要求,爲全局對象或其他對象分配標識符。從document

let scripts = document.scripts; 
 

 
let iife = scripts.namedItem("iife"); 
 

 
let iifeText = iife.textContent; 
 

 
let objs = iifeText.replace(/\(function\(\) \{|\}\(\)\)/g, "") 
 
    .replace(/(var|let|const)|[a-z_]+?\s=(?=\s\{|\{)|\s+/ig, "") 
 
    .replace(/(\w+)(?=:)/g, "\"$1\"") 
 
    .match(/[^;]+/g); 
 

 
let props = iifeText 
 
    .match(/(var|let|const)\s[a-z_]+?\s=?\s(?=\{)/ig) 
 
    .map(function(id) { 
 
    return id.replace(/var|let|const|\s+|=/g, ""); 
 
    }); 
 

 
let setProp = (obj, value) => { 
 
    // perform logic here 
 
    if (obj.age && 2017 - obj.age > value) { 
 
    obj.year_of_birth = 2017 - obj.age; 
 
    } 
 
    return obj 
 
} 
 

 
let getProp = (obj, value) => { 
 
    if (obj.age && 2017 - obj.age > value) { 
 
    return 2017 - obj.age; 
 
    } 
 
    return obj 
 
} 
 

 
for (let [key, prop] of props.entries()) { 
 
    this[prop] = setProp(JSON.parse(objs[key]), 27); 
 
} 
 

 
// remove original `script` 
 
iife.remove(); 
 

 
console.log(props, objs); 
 

 
for (let prop of props) { 
 
    // changed properties of objects 
 
    console.log(this[prop]); 
 
}
<script name="iife"> 
 
    (function() { 
 
    var john = { 
 
     age: 28, 
 
     year_of_birth: 1985 
 
    }; 
 
    var anne = { 
 
     age: 31, 
 
     year_of_birth: 1985 
 
    }; 
 
    }()); 
 
</script>

+0

@Shadow一旦對象已被解析,您可以在鏈接的答案中使用「代理」方法觀察,截獲get,set。對象。 – guest271314

0

刪除原<script>在一天結束的時候,把它歸結爲你是否有你的對象或沒有手柄的問題。如果你這樣做,很好,你可以改變它的.prototype__proto__,你可以用Object.defineProperty用你自己的邏輯來定義getter和setter。

如果您可以控制第三方對象在整個代碼中的分佈情況,甚至可以使用Proxy並替換引用。

如果你沒有對你的對象的引用,它只是在封閉的範圍內浮在背後,你什麼都不能做。


值得一提的是,在這些情況下,使用Facade design pattern可以被認爲是最好,那麼你可以有一切你想要的個性化定製,用自己的API進行引導。

相關問題