GVKun编程网logo

javascript – 使Meteor,Webstorm和Typescript协同工作的最佳做法是什么?(javascript prototype inheritence)

14

在本文中,您将会了解到关于javascript–使Meteor,Webstorm和Typescript协同工作的最佳做法是什么?的新资讯,同时我们还将为您解释javascriptprototypein

在本文中,您将会了解到关于javascript – 使Meteor,Webstorm和Typescript协同工作的最佳做法是什么?的新资讯,同时我们还将为您解释javascript prototype inheritence的相关在本文中,我们将带你探索javascript – 使Meteor,Webstorm和Typescript协同工作的最佳做法是什么?的奥秘,分析javascript prototype inheritence的特点,并给出一些关于asp.net – 超过了JavaScriptSerializer.MaxJsonLength.处理这个的最佳做法是什么?、How Javascript works (Javascript工作原理) (十五) 类和继承及 Babel 和 TypeScript 代码转换探秘、JavaScript .prototype 如何工作? - How does JavaScript .prototype work?、javascript – Node.js全局变量和TypeScript的实用技巧。

本文目录一览:

javascript – 使Meteor,Webstorm和Typescript协同工作的最佳做法是什么?(javascript prototype inheritence)

javascript – 使Meteor,Webstorm和Typescript协同工作的最佳做法是什么?(javascript prototype inheritence)

我使用Webstorm来管理Meteor项目,我很喜欢Typescript提供的强类型检查.

将Typescript转换为js有两个选项,一个是Webstorm的文件观察者,另一个是添加meteortypescript:compiler.

前者似乎更严格,因为如果我没有添加正确的引用会抱怨,但它无法处理现有文件,我是否必须将生成的js文件添加到VCS?否则,其他团队成员必须在从VCS更新后手动生成文件.

另一方面,由meteortypescript:compiler生成,使得tests / jasmine中的测试被veLocity忽略,这些测试是在Typescript中编写的,而不是在同一路径中生成js文件.

我应该使用哪些定义文件?

meteor add typescript-libs

在我的项目中没有添加任何.d.ts,如何引用它们?

mrt add typescript-libs

在packages文件夹中添加typescript-libs,但它似乎已过时.

tsd查询meteor –action install

安装更新版本的meteor.d.ts,但找不到铁:路由器和其他一些定义文件.

解决方法

将以下包添加到项目中.

meteor add meteortypescript:typescript-libs
meteor add meteortypescript:compiler

添加到.gitignore>> .TS

对于您创建的每个.ts文件(将编译为JS),您放在第一行的确如此:

/// <reference path=".meteor/local/build/programs/server/assets/packages/meteortypescript_typescript-libs/deFinitions/all-deFinitions.d.ts" />

请享用!

asp.net – 超过了JavaScriptSerializer.MaxJsonLength.处理这个的最佳做法是什么?

asp.net – 超过了JavaScriptSerializer.MaxJsonLength.处理这个的最佳做法是什么?

我使用jQuery的$.ajax()函数发送给客户端的大量数据.我在ASP.NET Web服务中调用返回JSON数据的方法.一切都适用于大多数搜索,但是当我有一个大的数据集返回时,我遇到了一个JavaScriptSerializer MaxJsonLength属性的问题.处理这个的最佳做法是什么?我不想只是任意设置一个最大长度.如果返回的数据大于当前的最大值,还是应该重新写入并向客户端发送数据卡,我可以在Web服务中设置MaxJsonLength吗?

以下是Web服务的相关代码段:

Dictionary<string,object> jsonValuePairs = new Dictionary<string,object>();
//add some data to the dictionary...
return System.Web.Script.Serialization.JavaScriptSerializer.Serialize(jsonValuePairs);

解决方法

从客户端脚本调用的web方法设置最大长度的唯一方法是通过web.config文件(如下).
设置此问题是什么?
我每次都会通过多个xhr调用来处理数据的部分数据.
<system.web.extensions>
  <scripting>
      <webServices>
        <jsonSerialization maxJsonLength="500000">
        </jsonSerialization>
      </webServices>
  </scripting>
</system.web.extensions>

更新:默认大小为2097152,相当于4 MB的Unicode字符串数据.你真的要把这么多的数据发回给客户吗?如果这样,你需要看看应用程序设计,因为用户体验会慢而繁琐.

How Javascript works (Javascript工作原理) (十五) 类和继承及 Babel 和 TypeScript 代码转换探秘

How Javascript works (Javascript工作原理) (十五) 类和继承及 Babel 和 TypeScript 代码转换探秘

个人总结:读完这篇文章需要15分钟,文章主要讲解了Babel和TypeScript的工作原理,(例如对es6 类的转换,是将原始es6代码转换为es5代码,这些代码中包含着类似于 _classCallCheck 和 _createClass这样的函数,而这些函数已经在Babel和TypeScript的标准库中预先定义好了,然后进行处理)。

顺便温习了Object.create这个方法,  比如有一个obj:{name:''是ho'',f:function(){alert(1)}}

var a = Object.create(obj)

这时,a对象的原型就是这个obj

以上等同于

var a 

a = {} //q是一个对象

a.__proto__= obj

 

类和继承及 Babel 和 TypeScript 代码转换探秘

这是 JavaScript 工作原理的第十五章。

如今使用类来组织各种软件工程代码是最常用的方法。本章将会探索实现 JavaScript 类的不同方法及如何构建类继承。我们将深入理解原型继承及分析使用流行的类库模拟实现基于类继承的方法。接下来,将会介绍如何使用转换器为语言添加非原生支持的语法功能和如何在 Babel 和 TypeScript 中运用以支持 ECMAScript 2015 类。最后介绍几个 V8 原生支持实现类的例子。

概述

JavaScript 没有原始类型且一切皆对象。比如,如下字符串:

const name = "SessionStack";

可以立即调用新创建对象上的不同方法:

console.log(a.repeat(2)); // 输出 SessionStackSessionStack
console.log(a.toLowerCase()); // 输出 sessionstack

JavaScript 和其它语言不一样,声明一个字符串或者数值会自动创建一个包含值的对象及提供甚至可以在原始类型上运行的不同方法。

另外一个有趣的事实即诸如数组的复杂数据类型也是对象。当使用 typeof 来检查一个数组实例的时候会输出 object。数组中每个元素的索引值即对象的属性。所以通过数组索引来访问元素的时候,实际上是在访问一个数组对象的属性然后获得属性值。当涉及到数据存储方式的时候,以下两种定义是相同的:

let names = [“SessionStack”];

let names = {
  “0”: “SessionStack”,
  “length”: 1
}

因此,访问数组元素和对象属性的速度是一样的。我走了很多弯路才发现该事实。以前有段时间,我得对项目中某段至关重要的代码进行大量的性能优化。当试验过其它简单的办法之后,我把所有的对象替换为数组。按理说,访问数组元素会比访问哈希图的键值更快。然而,我惊奇地发现没有半点性能的提升。在 JavaScript 中,所有的操作都是由访问哈希图中的键来实现的且耗时相同。

 

使用原型模拟类

当谈到对象的时候,首先映上眼帘的即类。开发人员习惯于使用类和类之间的关联来组织程序。虽然 JavaScript 中一切皆对象,但是并没有使用经典的基于类的继承。而是使用原型来实现继承。

 

在 JavaScript 中,每个对象关联其原型对象。当访问对象的一个方法或属性的时候,首先在对象自身进行搜索。如果没有找到,则在对象原型上进行查找。

让我们以定义基础类的构造函数为例:

function Component(content) {
  this.content = content;
}

Component.prototype.render = function() {
    console.log(this.content);
}

在原型上添加 render 函数,这样 Component 的实例就可以使用该方法。当调用该 Component 类实例的方法的时候,首先在实例上查询该方法。然后在原型上找到该渲染方法。

现在,尝试扩展 component 类,引入新的子类。

function InputField(value) {
    this.content = `<input type="text" value="${value}" />`;
}

如果想要 InputField 扩展 component 类的方法且可以调用其 render 方法,就需要更改其原型。当调用子类的实例方法的时候,肯定不希望在一个空原型上进行查找(这里其实所有对象都一个共同的原型,这里原文不够严谨)。该查找会延续到 Component 类上。

InputField.prototype = Object.create(new Component());

这样,就可以在 Component 类的原型上找到 render 方法。为了实现继承,需要把 InputField 的原型设置为Component 类的实例。大多数库使用 Object.setPrototypeOf 来实现继承。

然而,还有其它事情需要做。每次扩展类,所需要做的事如下:

  • 设置子类的原型为父类的实例
  • 在子类的构建函数中调用父类构造函数,这样才可以执行父类构造函数的初始化逻辑。
  • 引入访问父类的方法。当重写父类方法的时候,会想要调用父类方法的原始实现。

正如你所见,当想要实现所有基于类继承的功能的时候,每次都需要执行这么复杂的逻辑步骤。当需要创建这么多类的时候,即意味着需要把这些逻辑封装为可重用的函数。这就是开发者当初通过各种类库来模拟从而解决基于类的继承的问题。这些解决方案是如此流行,以至于迫切需要语言集成该功能。这就是为什么 ECMAScript 2015 的第一个重要修订版中引入了支持基于类继承的创建类的语法。

类转换

当在 ES6 或者 ECMAScript 2015 中提议新功能时,JavaScript 开发者社区就迫不及待想要引擎和浏览器实现支持。一种好的实现方法即通过代码转换。它允许使用 ECMAScript 2015 来进行代码编写然后转换为任何浏览器均可以运行的 JavaScript 代码。这包括使用基于类的继承来编写类并转换为可执行代码。

Babel 是最为流行的转换器之一。让我们通过 babel 转换 component 类来了解代码转换原理。

class Component {
  constructor(content) {
    this.content = content;
  }

  render() {
  	console.log(this.content)
  }
}

const component = new Component(''SessionStack'');
component.render();

以下为 Babel 是如何转换类定义的:

var Component = function () {
  function Component(content) {
    _classCallCheck(this, Component);

    this.content = content;
  }

  _createClass(Component, [{
    key: ''render'',
    value: function render() {
      console.log(this.content);
    }
  }]);

  return Component;
}();

如你所见,代码被转换为可在任意环境中运行的 ECMAScript 5 代码。另外,引入了额外的函数。它们是 Babel 标准库的一部分。编译后的文件中引入了 _classCallCheck 和 _createClass 函数。第一个函数保证构造函数永远不会被当成普通函数调用。这是通过检查函数执行上下文是否为一个 Component 对象实例来实现的。代码检查 this 是否指向这样的实例。第二个函数 _createClass 通过传入包含键和值的对象数组来创建对象(类)的属性。

为了理解继承的工作原理,让我们分析一下继承自 Component 类的 InputField 子类。

class InputField extends Component {
    constructor(value) {
        const content = `<input type="text" value="${value}" />`;
        super(content);
    }
}

这里是使用 Babel 来处理以上示例的输出:


var InputField = function (_Component) {
  _inherits(InputField, _Component);

  function InputField(value) {
    _classCallCheck(this, InputField);

    var content = ''<input type="text" value="'' + value + ''" />'';
    return _possibleConstructorReturn(this, (InputField.__proto__ || Object.getPrototypeOf(InputField)).call(this, content));
  }

  return InputField;
}(Component);

本例中,在 _inherits 函数中封装了继承逻辑。它执行了前面所说的一样的操作即设置子类的原型为父类的实例。

为了转换代码,Babel 执行了几次转换。首先,解析 ES6 代码并转化成被称为语法抽象树的中间展示层,语法抽象树在之前的文章有讲过了。该树会被转换为一个不同的语法抽象树,该树上每个节点会转换为对应的 ECMAScript 5 节点。最后,把语法抽象树转换为 ES5 代码。

Babel 中的语法抽象树

AST 由节点组成,每个节点只有一个父节点。Babel 中有一种基础类型节点。该节点包含节点的内容及在代码中的位置的信息。有各种不同类型的节点比如字面量表示字符串,数值,空值等等。也有控制流(if) 和 循环(for, while)的语句节点。另外,还有一种特殊类型的类节点。它是基础节点类的子类,通过添加字段变量来存储基础类的引用和把类的正文作为单独的节点来拓展自身。

转化以下代码片段为语法抽象树:

class Component {
  constructor(content) {
    this.content = content;
  }

  render() {
    console.log(this.content)
  }
}

以下为该代码片段的语法抽象树的大概情况:

创建语法抽象树后,每个节点转换为其对应的 ECMAScript 5 节点然后转化为遵循 ECMAScript 5 标准规范的代码。这是通过寻找离根节点最远的节点然后转换为代码。然后,他们的父节点通过使用每个子节点生成的代码片段来转化为代码,依次类推。该过程被称为 depth-first traversal 即深度优先遍历。

以上示例,首先生成两个 MethodDefinition 节点,之后类正文节点的代码,最后是 ClassDeclaration 节点的代码。

使用 TypeScript 进行转换

TypeScript 是另一个流行的框架。它引入了一种编写 JavaScript 程序的新语法,然后转换为任意浏览器或引擎可以运行的 EMCAScript 5 代码。以下为使用 Typescript 实现 component 类的代码:

class Component {
    content: string;
    constructor(content: string) {
        this.content = content;
    }
    render() {
        console.log(this.content)
    }
}

以下为语法抽象树示意图:

同样支持继承。

class InputField extends Component {
    constructor(value: string) {
        const content = `<input type="text" value="${value}" />`;
        super(content);
    }
}

代码转换结果如下:

var InputField = /** @class */ (function (_super) {
    __extends(InputField, _super);
    function InputField(value) {
        var _this = this;
        var content = "<input type=\"text\" value=\"" + value + "\" />";
        _this = _super.call(this, content) || this;
        return _this;
    }
    return InputField;
}(Component));

类似地,最后结果包含了一些来自 TypeScript 的类库代码。__extends 中封装了和之前第一部分讨论的一样的继承逻辑。

随着 Babel 和 TypeScript 的广泛使用,标准类和基于类的继承渐渐成为组织 JavaScript 程序的标准方式。这就推动了浏览器原生支持类。

 

类的原生支持

2014 年,Chrome 原生支持类。这就可以不使用任意库或者转换器来实现声明类的语法。

类的原生实现的过程即被称为语法糖的过程。这只是一个优雅的语法可以被转换为语言早已支持的相同的原语。使用新的易用的类定义,归根结底也是要创建构造函数和修改原型。

V8 引擎支持情况

让我们了解下 V8 是如何原生支持 ES6 类的。如前面文章所讨论的那样,首先解析新语法为可运行的 JavaScript 代码并添加到 AST 树中。类定义的结果即在语法抽象树中添加一个 ClassLiteral 类型的新节点。

该节点包含了一些信息。首先,它把构造函数当成单独的函数且包含类属性集。这些属性可以是一个方法,一个 getter, 一个 setter, 一个公共变量或者私有变量。该节点还储存了指向父类的指针引用,该父类也并储存了构造函数,属性集和及父类引用,依次类推。

一旦把新的 ClassLiteral 转换为字节码,再将其转化为各种函数和原型。

 

JavaScript .prototype 如何工作? - How does JavaScript .prototype work?

JavaScript .prototype 如何工作? - How does JavaScript .prototype work?

问题:

I''m not that into dynamic programming languages but I''ve written my fair share of JavaScript code. 我不喜欢动态编程语言,但是我写了相当一部分 JavaScript 代码。 I never really got my head around this prototype-based programming, does any one know how this works? 我从来没有真正了解过这种基于原型的编程,有人知道它是如何工作的吗?

var obj = new Object();
obj.prototype.test = function() { alert(''Hello?''); };
var obj2 = new obj();
obj2.test();

I remember a lot discussion I had with people a while back (I''m not exactly sure what I''m doing) but as I understand it, there''s no concept of a class. 我记得很久以前与人们进行过多次讨论(我不确定自己在做什么),但是据我了解,这里没有一个课堂的概念。 It''s just an object, and instances of those objects are clones of the original, right? 这只是一个对象,这些对象的实例是原始对象的副本,对吗?

But what is the exact purpose of this ".prototype" property in JavaScript? 但是,此 “.prototype” 属性在 JavaScript 中的确切目的是什么? How does it relate to instantiating objects? 它与实例化对象有何关系?

Update: correct way 更新:正确的方法

var obj = new Object(); // not a functional object
obj.prototype.test = function() { alert(''Hello?''); }; // this is wrong!

function MyObject() {} // a first class functional object
MyObject.prototype.test = function() { alert(''OK''); } // OK

Also these slides really helped a lot. 这些幻灯片也确实起到了很大作用。


解决方案:

参考一: https://stackoom.com/question/2P2H/JavaScript-prototype 如何工作
参考二: https://oldbug.net/q/2P2H/How-does-JavaScript-prototype-work

javascript – Node.js全局变量和TypeScript

javascript – Node.js全局变量和TypeScript

我需要一些强类型的全局变量.

如下所述:Extending TypeScript Global object in node.js,为了向全局变量添加字段,我需要添加一个扩展了node.d.ts中指定的Global接口的.d.ts文件.

另外,正如BaSarat所说:

Your file needs to be clean of any root level import or exports. That
would turn the file into a module and disconnect it from the global
type declaration namespace.

现在,我需要在Global接口上有字段,其类型是我创建的自定义接口:

declare namespace NodeJS{
    interface Global {
        foo: Foo
        bar: Bar
    }
}

我非常不愿意使用任何类型.

我可以将所有接口声明移动/复制到此声明文件,但这对我来说是一个糟糕的解决方案,因为Foo和Bar反过来会聚合其他接口的许多字段,包括Moment等第三方接口.

我需要一个解决这个悖论的方法

最佳答案
我发现这个有效.

有一个文件在NodeJS.Global接口上声明任何类型的属性.此文件必须清除导入或引用.

node.d.ts

declare namespace NodeJS{
    interface Global {
        foo: any
    }
}

然后在第二个文件中声明一个具有正确类型的全局变量.

global.d.ts

import IFoo from '../foo'

declare global {

  const foo:Ifoo

}

今天关于javascript – 使Meteor,Webstorm和Typescript协同工作的最佳做法是什么?javascript prototype inheritence的介绍到此结束,谢谢您的阅读,有关asp.net – 超过了JavaScriptSerializer.MaxJsonLength.处理这个的最佳做法是什么?、How Javascript works (Javascript工作原理) (十五) 类和继承及 Babel 和 TypeScript 代码转换探秘、JavaScript .prototype 如何工作? - How does JavaScript .prototype work?、javascript – Node.js全局变量和TypeScript等更多相关知识的信息可以在本站进行查询。

本文标签: