我最近开始学习JavaScript,当我完成prototype
概念时,我感到非常困惑。我阅读和理解的一切都让人感到困惑。
让我们直截了当..
我有两个与函数和对象有关的问题。
问题1:
JS中的函数可以有(key,value)属性对吗?如果是这样,那么密钥的数据类型可能是什么?因为在对象中,key
的{{1}}只能是[{1}},property
类型,在某些特殊情况下String
。
问题2:
内部评估的功能如何?它们是否转换为对象?
Object
和
Symbol
由于
答案 0 :(得分:2)
似乎你的整体问题是“什么是功能”。
是的,功能是对象*。这就是他们一等公民的原因。它们就像任何其他价值一样。就像其他对象一样,它们可以具有属性(您可能熟悉f.call
,f.bind
等)。
功能与其他对象的区别在于它们具有内部 [[Call]]
属性(无法从用户代码访问内部属性,它们在规范中用于定义内部状态/行为对象)。
[[Call]]
属性包含函数体中代码的一些表示。这是在调用函数时执行的代码。
函数需要其他内部属性,但[[Call]]
是最重要的属性。它用于确定对象是否可调用。
原型主要与功能无关。原型是一般应用于对象的概念。它们也不是很复杂:原型只是一个对象。使对象成为原型的原因是另一个对象通过其内部 [[Prototype]]
属性引用它。然后我们可以说“这个对象是另一个对象的原型”。
其他语言的工作方式相似。例如,Python允许您通过实现魔术def __call__:
方法来使类的实例可调用。
*:JavaScript中有七种数据类型:
前六个是所谓的“原始”数据类型。
答案 1 :(得分:1)
您可以随意向函数添加属性,因为JavaScript函数是对象。在为创建函数提供的两种语法中,都会得到一个(函数)对象。
添加属性的示例:
function counter() {
console.log(++counter.count);
}
counter.count = 0; // create a property on the function object
// Call the function several times
counter();
counter();
counter();
由于函数是对象,因此适用相同的限制:属性名称是字符串。价值观可以是任何东西属性未订购。
答案 2 :(得分:1)
我最好的建议是跳到Chrome控制台并在那里玩。在他们的地方装砖的真正好方法。
JS中的函数可以有(key,value)属性对吗?如果是这样, 我可能是密钥的数据类型?因为在一个对象中,关键 属性的类型只能是String,Object和某些类型 特殊情况符号。
当然可以。但是你误解了关于对象的一些关键。你可以这样做:
var obj = {};
var key = {};
obj[key] = "Smthg";
但这只会因为key
被字符串化而起作用。因此obj[key]
会转换为obj["[object Object]"]
。测试一下:
var obj = {};
var key = {};
obj[key] = "key1";
obj["[object Object]"] = 'key2';
console.log(obj[key]);
如您所见,无论您将使用多少个对象作为密钥 - 它们都会相互覆盖。
内部评估的功能如何?他们转变为 对象
JS是OOP语言 - 一切都是对象(除了一些原语等)。这意味着有许多不同的对象。并且他们互相继承了一些东西,否则会有一个GIANT对象,所有这些属性都有界限,无休止的等待时间来加载你的第一个“Hello World”应用程序。
我可能是学习JS的最佳工具,在读取一些读数之后是console.dir()
方法(如果在控制台模式下,则只是dir(someVar)
)。
创建对象 - var f = new Function()
和dir(f)
以查看它是什么以及它的原型等等。
答案 3 :(得分:1)
回答问题1:
是的,您可以在函数内部使用key:value对,但该函数名为constructor
。例如:
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
在ES6中:您可以在类中使用constructor()
函数存储类似的键:值对。例如:
constructor(make, modal, year) { // constructor syntactic sugar
this.make = make;
this.model = model;
this.year = year;
}
key
的数据类型取决于您在key
中存储的值的类型。在我们的示例中,如果我将字符串值存储在this.model
中,则模型键的数据类型将为字符串,如果我将年份存储为数字,则this.year
的数据类型将为number
回答问题2
要了解函数内部如何工作,您需要了解execution context
。要了解执行上下文,您必须阅读David的这篇文章。简单地说:
每次调用函数时,都会创建一个新的执行上下文。但是,在JavaScript解释器中,对执行上下文的每次调用都有两个阶段:
创作阶段
[调用函数时,但在执行之前 内部的任何代码]:创建范围链。创建变量,函数 和论点。确定"这个"的值。
激活/代码
执行阶段:分配值,对函数的引用和解释 /执行代码。
答案 4 :(得分:0)
现在这是一个很好的问题,可能会让很多人感到困惑。首先,javascript中有构造函数和原型的概念 所以
function A() {
console.log("A")
}
if you console.log(typeof(A)) // "function"
现在A还有一个原型
console.log("Aprototype", A.prototype)
这将是一个对象 该原生对象具有 proto
属性console.log(A.prototype.__proto__)
这将是父原型。从当前原型继承。这个父原型也将有一个构造函数,这是你的Function构造函数
console.log("parentConstructor", A.prototype.__proto__.constructor)
现在这个父Protype还有一个 proto ,它链接到Object函数构造函数
console.log("parent parent __proto__", A.prototype.__proto__.__proto__)
,它的构造函数是你的Object构造函数。
这就是为什么你能够获得新对象
var t = new Object()
看看我们如何像构造函数一样调用它。
这就是典型的javascript:)