从函数声明的堆栈中访问变量

问题描述 投票:1回答:5

在JavaScript中创建Stack的接口 - 使用函数样式而不是原型或伪古典样式时,下面的“storage”和“count”变量应分别为someInstance.storage和someInstance.count,以便它们可以在这个堆栈的实例以后呢?

随着变量现在被声明,一旦我们通过执行函数创建和堆栈实例,我们将失去访问权以查看计数(大小)和存储(堆栈中的属性)。

声明我们稍后需要使用功能创建模式访问的属性(而不是方法)的最佳方法是什么?

谢谢!

var Stack = function(){
  var someInstance = {};

  var storage = {};
  var count = 0;


  someInstance.push = function(value){
    storage[count++] = value;
  };

  someInstance.pop = function(){

    if(count){
      var popped = storage[--count];
    }

    delete storage[count];

    return popped;

  };

  someInstance.size = function(){
    return count;

  };

  return someInstance;
};

var stack = Stack();
javascript object data-structures stack
5个回答
1
投票

下面提到的私有变量可以在closure的javascript中进行研究。

参考:https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures

var Stack = function(){
  // PUBLIC
  var someInstance = {};

  // PRIVATE: Attach _ to private variables. (just implicit rule.)
  var _storage = {};
  var _count = 0;


  someInstance.push = function(value){
    storage[_count++] = value;
  };

  someInstance.pop = function(){

    if(_count){
      var popped = storage[--_count];
    }

    delete storage[_count];

    return popped;

  };

  someInstance._size = function(){
    return _count;

  };

  // if you assign public variable, you can access!!!
  someInstance.size = _size;
  someInstance.count = _count;

  return someInstance;
};

var stack = Stack();

1
投票

您可以在someInstance对象中添加getter和setter(由闭包提供),如下所示:

Object.defineProperty(someInstance, "count", {
   get: function() {
      return count;
   },
   set: function(value) {
      count = value;
   }
});

如果您希望能够获取值而不设置它,则可以省略set部分。

例:

var Stack = function(){
  var someInstance = {};

  var storage = {};
  var count = 0;

  Object.defineProperty(someInstance, "count", {
    get: function() {
      console.log("getter called");
      return count;
    },
    set: function(value) {
      console.log("setter called");
      count = value;
    }
  });

  return someInstance;
};

var stack = Stack();

console.log(stack.count);
stack.count = 55;
console.log(stack.count);

1
投票

storagecount是否应该是someInstance.storagesomeInstance.count取决于你希望这个实例的用户如何工作它。这有点基于意见。我的观点是堆栈不应该允许用户使用someInstance.count = 10之类的东西来改变计数,因为这样会破坏它。

我个人会让countstorage私有,这将防止直接访问可能发生的意外错误。一个很好的方法是在闭包中捕获它们并为count提供一个getter,这样你仍然可以读取计数,但不能改变它。就像是:

var Stack = function(){ 
    let storage = [], count = 0; // these will be caputured as a closure

    return {
        // the returned object will have push, pop, and a count getter
        push(v) {
            storage.push(v)
            count++
        },
        pop() {
            if (count) count--
            return storage.pop()
        },
        get count(){      // allow reading of count
            return count
        }

    } 
}
var stack =  Stack();
stack.push("hello");
stack.push("goodby");
stack.count = 10          // has no effect

console.log(stack.count)  // count is still 2
console.log(stack.pop())

console.log(stack.count)
console.log(stack.pop())

console.log(stack.count)

当然,由于这主要使用数组,你可以完全取消count变量,只需使用storage.length


0
投票

var Stack = function(){ 
    let storage = [], count = 0; // these will be caputured as a closure

    return {
        // the returned object will have push, pop, and a count getter
        push(v) {  //method
            storage.push(v)
            count++
        },
        pop: function() {
            if (count) count--
            return storage.pop()
        },
        get count(){      // allow reading of count
            return count
        },
		get insidebox(){      // allow reading of count
            return storage
        },
		callprice:function(cnt){		 
		var price=cnt*100;
		return price;
		}

    } 
}


Stack.prototype.price2 = function() {
    return "testpr";
};

var sb =  Stack();
console.log(sb.count);
sb.push('paint');
console.log(sb.insidebox);
console.log(sb.count); 
sb.push('Sharee');
console.log(sb.insidebox);
sb.push('Shirt'); 
sb.push('shoes');
console.log(sb.insidebox);
sb.pop();
console.log(sb.insidebox);
console.log(sb.count);
console.log(sb.callprice(sb.count));

0
投票

function Person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
}

Person.prototype.nationlity='Indian';

Person.prototype.fullname = function() {
    return this.firstName + " " + this.lastName
};

var myFather = new Person("Lalji", "Maurya", 50, "blue");
console.log(myFather.fullname());
console.log(myFather); 
console.log(myFather.nationlity); 

var myBrother = new Person("Ashish", "Maurya", 28, "black");
console.log(myBrother.fullname());
console.log(myBrother); 
console.log(myBrother.nationlity); 
© www.soinside.com 2019 - 2024. All rights reserved.