導航:首頁 > 編程語言 > js模板擴展函數

js模板擴展函數

發布時間:2023-08-18 23:14:08

1. js中幾種常見的高階函數

高階函數:英文叫Higher-order function。javaScript的函數其實都指向某個變數。既然變數可以指向函數,函數的參數能接收變數,那麼一個函數就可以接收另一個函數作為參數,這種函數就稱之為高階函數。

一個最簡單的高階函數:

編寫高階函數,就是讓函數的參數能夠接收別的函數。

下面介紹三個高階函數:

一、map/rece

如果你讀過Google的那篇大名鼎鼎的論文「MapRece: Simplified Data Processing on Large Clusters」,你就能大概明白map/rece的概念。由於map()方法定義在JavaScript的Array中,我們調用Array的map()方法,傳入我們自己的函數,就得到了一個新的Array作為結果:

1、map():

所以,map()作為高階函數,事實上它把運算規則抽象了,因此,我們不但可以計算簡單的f(x)=x2,還可以計算任意復雜的函數,比如,把Array的所有數字轉為字元串:

2、rece():

再看rece的用法。Array的rece()把一個函數作用在這個Array的[x1, x2, x3...]上,這個函數必須接收兩個參數,rece()把結果繼續和序列的下一個元素做累積計算,其效果就是:

二、filter

filter也是一個常用的操作,它用於把Array的某些元素過濾掉,然後返回剩下的元素。和map()類似,Array的filter()也接收一個函數。和map()不同的是,filter()把傳入的函數依次作用於每個元素,然後根據返回值是true還是false決定保留還是丟棄該元素。

可見用filter()這個高階函數,關鍵在於正確實現一個「篩選」函數。

回調函數:filter()接收的回調函數,其實可以有多個參數。通常我們僅使用第一個參數,表示Array的某個元素。回調函數還可以接收另外兩個參數,表示元素的位置和數組本身:

三、sort排序演算法

因為Array的sort()方法默認把所有元素先轉換為String再排序,結果'10'排在了'2'的前面,因為字元'1'比字元'2'的ASCII碼小。如果不知道sort()方法的默認排序規則,直接對數字排序,絕對栽進坑裡!

幸運的是,sort()方法也是一個高階函數,它還可以接收一個比較函數來實現自定義的排序。

2. 如何編寫 Node.js 擴展

一、編寫Node.js原生擴展

Node.js是一個強大的平台,理想狀態下一切都都可以用javascript寫成。然而,你可能還會用到許多遺留的庫和系統,這樣的話使用c++編寫Node.JS擴展會是一個不錯的注意。

以下所有例子的源代碼可在node擴展示例中找到 。

編寫Node.js C + +擴展很大程度上就像是寫V8的擴展; Node.js增加了一些介面,但大部分時間你都是在使原始的V8數據類型和方法,為了理解以下的代碼,你必須首先閱讀V8引擎嵌入指南。

Javascript版本的Hello World

在講解C++版本的例子之前,先讓我們來看看在Node.js中用Javascript編寫的等價模塊是什麼樣子。這是一個最簡單的Hello World,也不是通過HTTP,但它展示了node模塊的結構,而其介面也和大多數C++擴展要提供的介面差不多:

HelloWorldJs = function() {

this.m_count = 0;

};

HelloWorldJs.prototype.hello = function()

{

this.m_count++;

return 「Hello World」;

};

exports.HelloWorldJs = HelloWorldJs;

正如你所看到的,它使用prototype為HelloWorldJs類創建了一個新的方法。請注意,上述代碼通過將HelloWorldJS添加到exports變數來暴露構造函數。

要在其他地方使用該模塊,請使用如下代碼:

var helloworld = require(『helloworld_js』);

var hi = new helloworld.HelloWorldJs();

console.log(hi.hello()); // prints 「Hello World」 to stdout

C++版本的Hello World

要開始編寫C++擴展,首先要能夠編譯Node.js(請注意,我們使用的是Node.js 2.0版本)。本文所講內容應該兼容所有未來的0.2.x版本。一旦編譯安裝完node,編譯模塊就不在需要額外的東西了。

完整的源代碼可以在這里找到 。在使用Node.js或V8之前,我們需要包括相關的頭文件

#include <v8.h>

#include <node.h>

using namespace node;

using namespace v8;

在本例子中我直接使用了V8和node的命名空間,使代碼更易於閱讀。雖然這種用法和谷歌的自己的C++編程風格指南相悖,但由於你需要不停的使用V8定義的類型,所以目前為止的大多數node的擴展仍然使用了V8的命名空間。

接下來,聲明HelloWorld類。它繼承自node::ObjectWrap類 ,這個類提供了幾個如引用計數、在V8內部傳遞contex等的實用功能。一般來說,所有對象應該繼承ObjectWrap:

class HelloWorld: ObjectWrap

{

private:

int m_count;

public:

聲明類之後,我們定義了一個靜態成員函數,用來初始化對象並將其導入Node.js提供的target對象中。設個函數基本上是告訴Node.js和V8你的類是如何創建的,和它將包含什麼方法:

3. 如何編寫 Node.js 擴展

為了創建一個Node.js擴展,我們需要編寫一個繼承node::ObjectWrap的C++類。 ObjectWrap 實現了讓我們更容易與Javascript交互的公共方法


我們先來編寫類的基本框架:


現在,我們必須把下面的代碼編寫到我們的Init()方法中:


1.聲明構造函數,並將其綁定到我們的目標變數。var n = require("notification");將綁定notification() 到 n:n.notification().

1.聲明屬性:n.title 和n.icon.

?12345 // Set property accessors // SetAccessor arguments: Javascript property name, C++ method that will act as the getter, C++ method that will act as the setter Gtknotify::persistent_function_template->InstanceTemplate()->SetAccessor(String::New("title"), GetTitle, SetTitle); Gtknotify::persistent_function_template->InstanceTemplate()->SetAccessor(String::New("icon"), GetIcon, SetIcon); // For instance, n.title = "foo" will now call SetTitle("foo"), n.title will now call GetTitle()

1.聲明原型方法:n.send()

?123 // This is a Node macro to help bind C++ methods to Javascript methods (see https://github.com/joyent/node/blob/v0.2.0/src/node.h#L34) // Arguments: our constructor function, Javascript method name, C++ method name NODE_SET_PROTOTYPE_METHOD(Gtknotify::persistent_function_template, "send", Send);

剩下要做的就是編寫我們在Init方法中用的C++方法:New,GetTitle,SetTitle,GetIcon,SetIcon,Send

構造器方法: New()

New() 方法創建了我們自定義類的新實例(一個 Gtknotify 對象),並設置一些初始值,然後返回該對象的 JavaScript 處理。這是 JavaScript 使用 new 操作符調用構造函數的期望行為。


?12345678910111213141516 std::string title; std::string icon; // new notification() static Handle<Value> New(const Arguments& args) { HandleScope scope; Gtknotify* gtknotify_instance = new Gtknotify(); // Set some default values gtknotify_instance->title = "Node.js"; gtknotify_instance->icon = "terminal"; // Wrap our C++ object as a Javascript object gtknotify_instance->Wrap(args.This()); return args.This(); }

getters 和 setters: GetTitle(), SetTitle(), GetIcon(), SetIcon()

下面主要是一些樣板代碼,可以歸結為 C++ 和 JavaScript (v8) 之間的值轉換。


? // this.title static v8::Handle<Value> GetTitle(v8::Local<v8::String> property, const v8::AccessorInfo& info) { // Extract the C++ request object from the JavaScript wrapper. Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(info.Holder()); return v8::String::New(gtknotify_instance->title.c_str()); } // this.title= static void SetTitle(Local<String> property, Local<Value> value, const AccessorInfo& info) { Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(info.Holder()); v8::String::Utf8Value v8str(value); gtknotify_instance->title = *v8str; } // this.icon static v8::Handle<Value> GetIcon(v8::Local<v8::String> property, const v8::AccessorInfo& info) { // Extract the C++ request object from the JavaScript wrapper. Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(info.Holder()); return v8::String::New(gtknotify_instance->icon.c_str()); } // this.icon= static void SetIcon(Local<String> property, Local<Value> value, const AccessorInfo& info) { Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(info.Holder()); v8::String::Utf8Value v8str(value); gtknotify_instance->icon = *v8str; }

原型方法: Send()

首先我們抽取 C++ 對象的 this 引用,然後使用對象的屬性來構建通知並顯示。


?123456789101112131415161718 // this.send() static v8::Handle<Value> Send(const Arguments& args) { v8::HandleScope scope; // Extract C++ object reference from "this" Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(args.This()); // Convert first argument to V8 String v8::String::Utf8Value v8str(args[0]); // For more info on the Notify library: http://library.gnome.org/devel/libnotify/0.7/NotifyNotification.html Notify::init("Basic"); // Arguments: title, content, icon Notify::Notification n(gtknotify_instance->title.c_str(), *v8str, gtknotify_instance->icon.c_str()); // *v8str points to the C string it wraps // Display the notification n.show(); // Return value return v8::Boolean::New(true); }

編譯擴展

node-waf 是一個構建工具,用來編譯 Node 的擴展,這是 waf 的基本封裝。構建過程可通過名為 wscript 的文件進行配置。


?1234567891011121314151617 def set_options(opt): opt.tool_options("compiler_cxx") def configure(conf): conf.check_tool("compiler_cxx") conf.check_tool("node_addon") # This will tell the compiler to link our extension with the gtkmm and libnotifymm libraries. conf.check_cfg(package='gtkmm-2.4', args='--cflags --libs', uselib_store='LIBGTKMM') conf.check_cfg(package='libnotifymm-1.0', args='--cflags --libs', uselib_store='LIBNOTIFYMM') def build(bld): obj = bld.new_task_gen("cxx", "shlib", "node_addon") obj.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall"] # This is the name of our extension. obj.target = "gtknotify" obj.source = "src/node_gtknotify.cpp" obj.uselib = ['LIBGTKMM', 'LIBNOTIFYMM']

現在我們已經准備好要開始構建了,在頂級目錄下運行如下命令:


?1 node-waf configure && node-waf build

如果一切正常,我們將得到編譯過的擴展,位於:./build/default/gtknotify.node ,來試試:


?123456 $ node > var notif = require('./build/default/gtknotify.node'); > n = new notif.notification(); { icon: 'terminal', title: 'Node.js' } > n.send("Hello World!"); true

上述的代碼將在你的屏幕右上方顯示一個通知信息。


打成npm包

這是非常酷的, 但是怎樣與Node社區分享你的努力的成果呢? 這才是npm主要的用途: 使它更加容易擴展和分發.


打npm的擴展包是非常簡單的. 你所要做的就是在你的頂級目錄中創建一個包含你的擴展信息的文件package.json :


?2526272829303132333435 { // 擴展的名稱 (不要在名稱中包含node 或者 js, 這是隱式關鍵字). // 這是通過require() 導入擴展的名稱. "name" : "notify", // Version should be http://semver.org/ compliant "version" : "v0.1.0" // 這些腳本將在調用npm安裝和npm卸載的時候運行. , "scripts" : { "preinstall" : "node-waf configure && node-waf build" , "preuninstall" : "rm -rf build/*" } // 這是構建我們擴展的相對路徑. , "main" : "build/default/gtknotify.node" // 以下是可選欄位: , "description" : "Description of the extension...." , "homepage" : "https://github.com/olalonde/node-notify" , "author" : { "name" : "Olivier Lalonde" , "email" : "[email protected]" , "url" : "http://www.syskall.com/" } , "repository" : { "type" : "git" , "url" : "https://github.com/olalonde/node-notify.git" } }

關於package.json 格式的更多細節, 可以通過 npm help json 獲取文檔. 注意 大多數欄位都是可選的.

skyline520

翻譯於 2年前

0人頂

頂 翻譯的不錯哦!


你現在可以在你的頂級目錄中通過運行npm install 來安裝你的新的npm包了. 如果一切順利的話, 應該可以簡單的載入你的擴展 var notify = require('你的包名');. 另外一個比較有用的命令式 npm link 通過這個命令你可以創建一個到你開發目錄的鏈接,當你的代碼發生變化時不必每次都去安裝/卸載.


假設你寫了一個很酷的擴展, 你可能想要在中央npm庫發布到網上. 首先你要先創建一個賬戶:


?1 $ npm adser

下一步, 回到你的根目錄編碼並且運行:


?1 $ npm publish

就是這樣, 你的包現在已經可以被任何人通過npm install 你的包名命令來安裝了.

閱讀全文

與js模板擴展函數相關的資料

熱點內容
win10ime 瀏覽:271
手機號大數據保護停機是什麼意思 瀏覽:81
兩個蘋果手機怎麼隔空投送app 瀏覽:903
ps修改有褶皺的文件 瀏覽:417
javadbfreader 瀏覽:307
蘋果手機數字代碼是什麼 瀏覽:66
驅動程序順序安裝腳本 瀏覽:665
word文件里怎樣查重 瀏覽:219
mx5系統基帶版本 瀏覽:184
ntlea全域通win10 瀏覽:171
qq怎麼查看別人的收藏 瀏覽:135
地震三參數matlab程序 瀏覽:57
怎樣給優盤文件加密軟體 瀏覽:7
收拾文件有哪些小妙招 瀏覽:431
pdf文件去底網 瀏覽:253
win10重裝系統需要格式化c盤嗎 瀏覽:424
路由器trx文件 瀏覽:655
淘寶店鋪數據包怎麼做 瀏覽:195
win10鍵盤黏連 瀏覽:332
json如何生成表格 瀏覽:323

友情鏈接