整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          如何將檢索增強(qiáng)生成 (RAG) 用于 Go 應(yīng)用程序

          如何將檢索增強(qiáng)生成 (RAG) 用于 Go 應(yīng)用程序

          本文中,學(xué)習(xí)如何實現(xiàn) RAG(使用 LangChain 和 PostgreSQL)以提高 LLM 輸出的準(zhǔn)確性和相關(guān)性。

          由于強(qiáng)大的機(jī)器學(xué)習(xí)模型(特別是大型語言模型,如 Claude、Meta 的 LLama 2 等)被托管平臺/服務(wù)作為 API 調(diào)用公開,生成式 AI 開發(fā)已經(jīng)民主化。這使開發(fā)人員擺脫了對基礎(chǔ)設(shè)施的擔(dān)憂,并讓他們專注于核心業(yè)務(wù)問題。這也意味著開發(fā)人員可以自由使用最適合其解決方案的編程語言。Python 通常是 AI/ML 解決方案的首選語言,但該領(lǐng)域具有更大的靈活性。

          在這篇文章中,您將看到如何利用 Go 編程語言將向量數(shù)據(jù)庫和諸如檢索增強(qiáng)生成 (RAG) 等技術(shù)與 langchaingo 一起使用。如果您是想要如何構(gòu)建和學(xué)習(xí)生成式 AI 應(yīng)用程序的 Go 開發(fā)人員,那么您來對地方了!

          如果你正在尋找有關(guān)使用 Go for AI/ML 的介紹性內(nèi)容,請隨時查看我以前的博客和這個領(lǐng)域的開源項目。

          首先,讓我們退后一步,在深入了解本文的動手部分之前了解一些背景信息。

          LLM的局限性

          大型語言模型 (LLM) 和其他基礎(chǔ)模型已經(jīng)在大量數(shù)據(jù)語料庫上進(jìn)行了訓(xùn)練,使它們能夠在許多自然語言處理 (NLP) 任務(wù)中表現(xiàn)出色。但最重要的限制之一是,大多數(shù)基礎(chǔ)模型和 LLM 使用靜態(tài)數(shù)據(jù)集,該數(shù)據(jù)集通常具有特定的知識截止點(例如,2022 年 1 月)。

          例如,如果你要問一個發(fā)生在截止時間之后的事件,它要么無法回答(這很好),要么更糟,自信地回答不正確的回答——這通常被稱為幻覺。

          我們需要考慮這樣一個事實,即 LLM 只根據(jù)他們接受訓(xùn)練的數(shù)據(jù)做出回應(yīng)——這限制了他們準(zhǔn)確回答有關(guān)專業(yè)或?qū)S兄黝}的問題的能力。例如,如果我要問一個關(guān)于特定AWS服務(wù)的問題,LLM可能會(也可能不會)給出準(zhǔn)確的答案。如果 LLM 可以使用官方的 AWS 服務(wù)文檔作為參考,那不是很好嗎?

          RAG(檢索增強(qiáng)生成)有助于緩解這些問題

          它通過在響應(yīng)生成過程中動態(tài)檢索外部信息來增強(qiáng) LLM,從而將模型的知識庫擴(kuò)展到其原始訓(xùn)練數(shù)據(jù)之外。基于RAG的解決方案包含一個向量存儲,可以對其進(jìn)行索引和查詢以檢索最新和相關(guān)的信息,從而將LLM的知識擴(kuò)展到其訓(xùn)練截止點之外。當(dāng)配備 RAG 的 LLM 需要生成響應(yīng)時,它首先查詢向量存儲以查找與查詢相關(guān)的相關(guān)最新信息。這個過程確保模型的輸出不僅基于其預(yù)先存在的知識,而且用最新信息進(jìn)行擴(kuò)充,從而提高其響應(yīng)的準(zhǔn)確性和相關(guān)性。

          但是,RAG并不是唯一的方法

          雖然這篇文章只關(guān)注 RAG,但還有其他方法可以解決這個問題,每種方法都有其優(yōu)點和缺點:

          • 特定于任務(wù)的調(diào)整:在特定任務(wù)或數(shù)據(jù)集上微調(diào)大型語言模型,以提高它們在這些領(lǐng)域的性能。
          • 提示工程: 仔細(xì)設(shè)計輸入提示,以引導(dǎo)語言模型實現(xiàn)所需的輸出,而無需進(jìn)行重大的體系結(jié)構(gòu)更改。
          • 少樣本和零樣本學(xué)習(xí):使語言模型能夠適應(yīng)新任務(wù)的技術(shù),而這些任務(wù)的訓(xùn)練數(shù)據(jù)有限或沒有額外的訓(xùn)練數(shù)據(jù)。

          矢量存儲和嵌入

          我在上一段中多次提到向量存儲。這些只不過是存儲和索引向量嵌入的數(shù)據(jù)庫,這些向量嵌入是文本、圖像或?qū)嶓w等數(shù)據(jù)的數(shù)值表示。嵌入幫助我們超越基本搜索,因為它們代表了源數(shù)據(jù)的語義含義——因此有了語義搜索這個詞,它是一種理解單詞的含義和上下文以提高搜索準(zhǔn)確性和相關(guān)性的技術(shù)。矢量數(shù)據(jù)庫還可以存儲元數(shù)據(jù),包括對嵌入的原始數(shù)據(jù)源(例如,Web 文檔的 URL)的引用。

          得益于生成式人工智能技術(shù),矢量數(shù)據(jù)庫也出現(xiàn)了爆炸式增長。其中包括已建立的 SQL 和 NoSQL 數(shù)據(jù)庫,您可能已經(jīng)在體系結(jié)構(gòu)的其他部分(例如 PostgreSQL、Redis、MongoDB 和 OpenSearch)中使用這些數(shù)據(jù)庫。但也有為矢量存儲定制的數(shù)據(jù)庫。其中一些包括 Pinecone、Milvus、Weaviate 等。

          好吧,讓我們回到 RAG...

          典型的 RAG 工作流程是什么樣的?

          概括地說,基于 RAG 的解決方案具有以下工作流。這些通常作為有凝聚力的管道執(zhí)行:

          • 從各種外部來源(如文檔、圖像、Web URL、數(shù)據(jù)庫、專有數(shù)據(jù)源等)檢索數(shù)據(jù)。這包括子步驟,例如分塊,它涉及將大型數(shù)據(jù)集(例如 100 MB PDF 文件)拆分為較小的部分(用于索引)。
          • 創(chuàng)建嵌入: 這涉及使用嵌入模型將數(shù)據(jù)轉(zhuǎn)換為數(shù)值表示。
          • 矢量存儲中的存儲/索引嵌入

          歸根結(jié)底,這是作為更大應(yīng)用程序的一部分的集成,其中上下文數(shù)據(jù)(語義搜索結(jié)果)提供給 LLM(以及提示)。

          端到端 RAG 工作流的實際應(yīng)用

          每個工作流步驟都可以使用不同的組件執(zhí)行。博客中使用的包括:

          • PostgreSQL: 由于 pgvector 擴(kuò)展,它將用作向量數(shù)據(jù)庫。為了簡單起見,我們將在 Docker 中運行它。
          • langchaingo: 它是 langchain 框架的 Go 端口。它為各種組件提供插件,包括矢量存儲。我們將使用它從 Web URL 加載數(shù)據(jù)并在 PostgreSQL 中將其編入索引。
          • 文本和嵌入模型: 我們將使用 Amazon Bedrock Claude 和 Titan 模型(分別用于文本和嵌入)和 langchaingo。
          • 檢索和應(yīng)用集成:langchaingo vector store(用于語義搜索)和 chain(用于 RAG)。

          您將了解這些單獨的部分是如何工作的。我們將在隨后的博客中介紹此體系結(jié)構(gòu)的其他變體。

          準(zhǔn)備工作

          確保您擁有:

          • 安裝了 Go、Docker 和 psql(例如,如果您在 Mac 上,則使用 Homebrew)。
          • 從本地計算機(jī)配置的 Amazon Bedrock 訪問 - 有關(guān)詳細(xì)信息,請參閱此博客文章。

          在 Docker 上啟動 PostgreSQL

          我們可以使用一個 Docker 鏡像!

          docker run --name pgvector --rm -it -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres ankane/pgvector
          


          通過從其他終端登錄 PostgreSQL(使用 )來激活擴(kuò)展:pgvectorpsql

          # enter postgres when prompted for password
          psql -h localhost -U postgres -W
          
          CREATE EXTENSION IF NOT EXISTS vector;
          


          將數(shù)據(jù)加載到 PostgreSQL (Vector Store)

          克隆項目存儲庫:

          git clone https://github.com/build-on-aws/rag-golang-postgresql-langchain
          cd rag-golang-postgresql-langchain
          


          此時,我假設(shè)您的本地計算機(jī)已配置為使用 Amazon Bedrock

          我們要做的第一件事是將數(shù)據(jù)加載到 PostgreSQL 中。在這種情況下,我們將使用現(xiàn)有的網(wǎng)頁作為信息來源。我已經(jīng)使用過這個開發(fā)人員指南——但請隨意使用你自己的!請確保在后續(xù)步驟中相應(yīng)地更改搜索查詢。

          export PG_HOST=localhost
          export PG_USER=postgres
          export PG_PASSWORD=postgres
          export PG_DB=postgres
          
          go run *.go -action=load -source=https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html
          


          應(yīng)獲得以下輸出:

          loading data from https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html
          vector store ready - postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable
          no. of documents to be loaded 23
          


          給它幾秒鐘。最后,如果一切順利,您應(yīng)該會看到以下輸出:

          data successfully loaded into vector store
          


          要進(jìn)行驗證,請返回終端并檢查表:psql

          \d
          


          您應(yīng)該會看到幾個表 — 和 .這些是創(chuàng)建的,因為我們沒有明確指定它們(沒關(guān)系,方便入門! 包含集合名稱,同時存儲實際的嵌入。langchain_pg_collectionlangchain_pg_embeddinglangchaingolangchain_pg_collectionlangchain_pg_embedding

          | Schema | Name                    | Type  | Owner    |
          |--------|-------------------------|-------|----------|
          | public | langchain_pg_collection | table | postgres |
          | public | langchain_pg_embedding  | table | postgres |
          


          您可以自省這些表:

          select * from langchain_pg_collection;
          select count(*) from langchain_pg_embedding;
          
          select collection_id, document, uuid from langchain_pg_embedding LIMIT 1;
          


          您將在langchain_pg_embedding表中看到 23 行,因為這是我們的網(wǎng)頁源被拆分為 langchain 文檔的數(shù)量(當(dāng)您加載數(shù)據(jù)時,請參閱上面的應(yīng)用程序日志)

          快速繞道了解其工作原理......

          數(shù)據(jù)加載實現(xiàn)在 load.go 中,但讓我們看看我們?nèi)绾卧L問向量存儲實例(在 common.go 中):

              brc :=bedrockruntime.NewFromConfig(cfg)
          
              embeddingModel, err :=bedrock.NewBedrock(bedrock.WithClient(brc), bedrock.WithModel(bedrock.ModelTitanEmbedG1))
             //...
              store, err=pgvector.New(
                  context.Background(),
                  pgvector.WithConnectionURL(pgConnURL),
                  pgvector.WithEmbedder(embeddingModel),
              )
          


          • pgvector.WithConnectionURL是提供 PostgreSQL 實例連接信息的位置
          • pgvector.WithEmbedder是有趣的部分,因為這是我們可以插入我們選擇的嵌入模型的地方。 支持 Amazon Bedrock 嵌入。在本例中,我使用了 Amazon Bedrock Titan 嵌入模型。langchaingo

          回到 load.go 中的加載過程。為此,我們首先使用內(nèi)置的 HTML 加載器以 ( 函數(shù)) 切片的形式獲取數(shù)據(jù)。schema.DocumentgetDocslangchaingo

          docs, err :=documentloaders.NewHTML(resp.Body).LoadAndSplit(context.Background(), textsplitter.NewRecursiveCharacter())
          


          然后,我們將其加載到 PostgreSQL 中。與其自己寫所有東西,不如使用向量存儲抽象,使用高級函數(shù):langchaingoAddDocuments

          _, err=store.AddDocuments(context.Background(), docs)
          


          偉大。我們設(shè)置了一個簡單的管道來獲取數(shù)據(jù)并將其攝取到 PostgreSQL 中。讓我們好好利用吧!

          執(zhí)行語義搜索

          讓我們問一個問題。我將使用“我可以使用哪些工具來設(shè)計 dynamodb 數(shù)據(jù)模型?”,這與我用作數(shù)據(jù)源的文檔相關(guān) - 請根據(jù)您的場景隨意調(diào)整它。

          export PG_HOST=localhost
          export PG_USER=postgres
          export PG_PASSWORD=postgres
          export PG_DB=postgres
          
          go run *.go -action=semantic_search -query="what tools can I use to design dynamodb data models?" -maxResults=3
          


          您應(yīng)該會看到類似的輸出 — 請注意,我們選擇最多輸出三個結(jié)果(您可以更改它):

          vector store ready==============similarity search results==============similarity search info - can build new data models from, or design models based on, existing data models that satisfy
                  your application's data access patterns. You can also import and export the designed data
                  model at the end of the process. For more information, see Building data models with NoSQL Workbench
          similarity search score - 0.3141409============================similarity search info - NoSQL Workbench for DynamoDB is a cross-platform, client-side GUI
                  application that you can use for modern database development and operations. It's available
                  for Windows, macOS, and Linux. NoSQL Workbench is a visual development tool that provides
                  data modeling, data visualization, sample data generation, and query development features to
                  help you design, create, query, and manage DynamoDB tables. With NoSQL Workbench for DynamoDB, you
          similarity search score - 0.3186116============================similarity search info - key-value pairs or document storage. When you switch from a relational database management
                system to a NoSQL database system like DynamoDB, it's important to understand the key differences
                and specific design approaches.TopicsDifferences between relational data
                    design and NoSQLTwo key concepts for NoSQL designApproaching NoSQL designNoSQL Workbench for DynamoDB
                Differences between relational data
                    design and NoSQL
          similarity search score - 0.3275382============================


          現(xiàn)在你在這里看到的是前三個結(jié)果(感謝)。-maxResults=3

          請注意,這不是我們問題的答案。這些是來自我們的向量存儲的結(jié)果,它們在語義上接近查詢——這里的關(guān)鍵字是語義。多虧了 中的向量存儲抽象,我們能夠輕松地將源數(shù)據(jù)攝取到 PostgreSQL 中,并使用該函數(shù)獲得與我們的查詢相對應(yīng)的頂級結(jié)果(參見 query.go 中的函數(shù)):langchaingoSimilaritySearchNsemanticSearch

          請注意,(在撰寫本文時)langchaingo 中的 pgvector 實現(xiàn)使用余弦距離向量運算,但 pgvector 也支持 L2 和內(nèi)積 - 有關(guān)詳細(xì)信息,請參閱 pgvector 文檔。

          好的,到目前為止,我們有:

          • 加載的矢量數(shù)據(jù)
          • 已執(zhí)行的語義搜索

          這是 RAG(檢索增強(qiáng)生成)的墊腳石 - 讓我們看看它的實際效果!

          使用 RAG 進(jìn)行智能搜索

          為了執(zhí)行基于 RAG 的搜索,我們運行與上面相同的命令(幾乎),只是 () 略有變化:actionrag_search

          export PG_HOST=localhost
          export PG_USER=postgres
          export PG_PASSWORD=postgres
          export PG_DB=postgres
          
          go run *.go -action=rag_search -query="what tools can I use to design dynamodb data models?" -maxResults=3
          


          這是我得到的輸出(在您的情況下可能略有不同):

          Based on the context provided, the NoSQL Workbench for DynamoDB is a tool that can be used to design DynamoDB data models. Some key points about NoSQL Workbench for DynamoDB:
          
          - It is a cross-platform GUI application available for Windows, macOS, and Linux.
          - It provides data modeling capabilities to help design and create DynamoDB tables.
          - It allows you to build new data models or design models based on existing data models.
          - It provides features like data visualization, sample data generation, and query development to manage DynamoDB tables.
          - It helps in understanding the key differences and design approaches when moving from a relational database to a NoSQL database like DynamoDB.
          


          因此,總而言之,NoSQL Workbench for DynamoDB 似乎是一個專門為建模和使用 DynamoDB 數(shù)據(jù)模型而設(shè)計的有用工具。

          正如你所看到的,結(jié)果不僅僅是“這是你的查詢的前 X 個響應(yīng)”。相反,這是對這個問題的精心設(shè)計的回答。讓我們再次窺探幕后花絮,看看它是如何工作的。

          與攝取和語義搜索不同,基于 RAG 的搜索不會直接由向量存儲實現(xiàn)公開。為此,我們使用一條鏈來處理以下事項:langchaingolangchaingo

          • 調(diào)用語義搜索
          • 將語義搜索與提示相結(jié)合
          • 將其發(fā)送到大型語言模型 (LLM),在本例中,該模型恰好是 Amazon Bedrock 上的 Claude。

          這是鏈的樣子(參考 query.go 中的函數(shù)):ragSearch

              result, err :=chains.Run(
                  context.Background(),
                  chains.NewRetrievalQAFromLLM(
                      llm,
                      vectorstores.ToRetriever(store, numOfResults),
                  ),
                  question,
                  chains.WithMaxTokens(2048),
              )
          


          讓我們再試一個

          這只是一個例子。我嘗試了一個不同的問題,并將 maxResults 增加到 10,這意味著將使用向量數(shù)據(jù)庫中的前 10 個結(jié)果來制定答案。

          go run *.go -action=rag_search -query="how is NoSQL different from SQL?" -maxResults=10
          


          結(jié)果(同樣,對你來說可能不同):

          Based on the provided context, there are a few key differences between NoSQL databases like DynamoDB and relational database management systems (RDBMS):
          
          1. Data Modeling:
             - In RDBMS, data modeling is focused on flexibility and normalization without worrying much about performance implications. Query optimization doesn't significantly affect schema design.
             - In NoSQL, data modeling is driven by the specific queries and access patterns required by the application. The data schema is designed to optimize the most common and important queries for speed and scalability.
          
          2. Data Organization:
             - RDBMS organizes data into tables with rows and columns, allowing flexible querying.
             - NoSQL databases like DynamoDB use key-value pairs or document storage, where data is organized in a way that matches the queried data shape, improving query performance.
          
          3. Query Patterns:
             - In RDBMS, data can be queried flexibly, but queries can be relatively expensive and don't scale well for high-traffic situations.
             - In NoSQL, data can be queried efficiently in a limited number of ways defined by the data model, while other queries may be expensive and slow.
          
          4. Data Distribution:
             - NoSQL databases like DynamoDB distribute data across partitions to scale horizontally, and the data keys are designed to evenly distribute the traffic across partitions, avoiding hot spots.
             - The concept of "locality of reference," keeping related data together, is crucial for improving performance and reducing costs in NoSQL databases.
          
          In summary, NoSQL databases prioritize specific query patterns and scalability over flexible querying, and the data modeling is tailored to these requirements, in contrast with RDBMS where data modeling focuses on normalization and flexibility.
          


          從這里“去”哪里?

          邊做邊學(xué)是一個很好的方法。如果您到目前為止已經(jīng)遵循并執(zhí)行了該應(yīng)用程序,那就太好了!
          我建議您嘗試以下方法:

          • langchaingo支持許多不同的模型,包括 Amazon Bedrock 中的模型(例如 Meta LLama 2、Cohere 等)——嘗試調(diào)整模型,看看它是否有所作為。輸出更好嗎?
          • 矢量數(shù)據(jù)庫呢?我演示了 PostgreSQL,但也支持其他(包括 OpenSearch、Chroma 等) - 嘗試交換 Vector 存儲,看看搜索結(jié)果如何/是否不同。langchaingo
          • 您可能了解要點,但您也可以嘗試不同的嵌入模型。我們使用了 Amazon Titan,但也支持許多其他模型,包括 Amazon Bedrock 中的 Cohere 嵌入模型。langchaingo

          ?

          這是一個簡單示例,可讓您更好地了解構(gòu)建基于 RAG 的解決方案的各個步驟。這些可能會根據(jù)實現(xiàn)而略有變化,但高級想法保持不變。

          我用作框架。但這并不總是意味著你必須使用一個。如果您需要在應(yīng)用程序中進(jìn)行精細(xì)控制或框架不符合您的要求,您還可以刪除抽象并直接調(diào)用 LLM 平臺 API。與大多數(shù)生成式 AI 一樣,這個領(lǐng)域正在迅速發(fā)展,我對 Go 開發(fā)人員有更多選擇來構(gòu)建生成式 AI 解決方案持樂觀態(tài)度。langchaingo

          如果您有任何反饋或問題,或者您希望我圍繞此主題介紹其他內(nèi)容,請隨時在下面發(fā)表評論!

          祝您建造愉快!


          原文標(biāo)題:How To Use Retrieval Augmented Generation (RAG) for Go Applications

          原文鏈接:https://dzone.com/articles/how-to-use-retrieval-augmented-generation-rag-for

          作者:Abhishek Gupta

          編譯:LCR

          、ready加載事件

          ready()類似于 onLoad()事件

          ready()可以寫多個,按順序執(zhí)行

          $(document).ready(function(){})等價于$(function(){})

          <!DOCTYPE html>
          <html>
              <head>
                  <meta charset="utf-8">
                  <title>ready事件</title>
                  <script src="js/jquery-3.4.1.js" type="text/javascript"></script>
                  <script type="text/javascript">
                      // 文檔載入完便觸發(fā)ready方法
                      $(document).ready(function(){
                          $("div").html("ready go...");
                      })
                      // $(document).ready(function(){})==$(function(){}) 
                      $(function(){
                          $("p").click( function () {
                              $(this).hide(); 
                          });
                      });
                      $(function(){
                          $("#btntest").bind("click",function(){
                              $("div").html("剁吧...");
                          });
                      });
                  </script>
              </head>
              <body>
                  <h3>頁面載入時觸發(fā)ready()事件</h3>
                  <div></div>
                  <input id="btntest" type="button" value="剁手" />
                  <p>aaa</p>
                  <p>bbbb</p>
                  <p>ccc</p>
                  <p>dddd</p>
              </body>
          </html>


          2、bind()綁定事件

          為被選元素添加一個或多個事件處理程序,并規(guī)定事件發(fā)生時運行的函數(shù)。

          $(selector).bind( eventType [, eventData], handler(eventObject));

          eventType :是一個字符串類型的事件類型,就是你所需要綁定的事件。

          這類類型可以包括如下:

          blur, focus, focusin, focusout, load, resize, scroll, unload, click, dblclick

          mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter

          mouseleave,change, select, submit, keydown, keypress, keyup, error

          [, eventData]:傳遞的參數(shù),格式:{名:值,名2:值2}

          handler(eventObject):該事件觸發(fā)執(zhí)行的函數(shù)

          3、簡單的bind()事件

          <script type="text/javascript">
              $(function(){
                  /*$("#test").bind("click",function(){
                      alert("世界會向那些有目標(biāo)和遠(yuǎn)見的人讓路!!");
                  });*/
                  /*
                   * js的事件綁定
                      ele.onclick=function(){};
                   * */
                  // 等同于上面的放方法
                  $("#test").click(function(){
                      alert("世界會向那些有目標(biāo)和遠(yuǎn)見的人讓路!!");
                  });
                  /*
                   1.確定為哪些元素綁定事件
                      獲取元素
                   2.綁定什么事件(事件類型)
                      第一個參數(shù):事件的類型
                   3.相應(yīng)事件觸發(fā)的,執(zhí)行的操作
                      第二個參數(shù):函數(shù)
                   * */
                  $("#btntest").bind('click',function(){
                      // $(this).attr('disabled',true);
                      $(this).prop("disabled",true);
                  })
              });
              </script>
          <body>
              <h3>bind()方簡單的綁定事件</h3>
              <div id="test" style="cursor:pointer">點擊查看名言</div>
              <input id="btntest" type="button" value="點擊就不可用了" />
          </body>

          4、綁定多個事件

          <script type="text/javascript">
              $(function(){
                  // 綁定click 和 mouseout事件
                  /*$("h3").bind('click mouseout',function(){
                      console.log("綁多個事件");
                  });*/
                  // 鏈?zhǔn)骄幊?
                  $("h3").bind('click',function(){
                      alert("鏈?zhǔn)骄幊?");
                  }).bind('mouseout',function(){
                      $("#slowDiv").show("slow");//讓slowDiv顯示
                  });
                  /*$("#test").click(function(){
                      console.log("點擊鼠標(biāo)了....");
                  }).mouseout(function () {
                      console.log("移出鼠標(biāo)了...");
                  });*/
                  $("#test").bind({
                      click:function(){
                          alert("鏈?zhǔn)骄幊?");
                      },
                      mouseout:function(){
                          $("#slowDiv").show("slow");
                      }
                  });
              });
          </script>
          <body>
              <h3>bind()方法綁多個事件</h3>
              <div id="test" style="cursor:pointer">點擊查看名言</div>
              <div id="slowDiv"style=" width:200px; height:200px; display:none; ">
                  人之所以能,是相信能
              </div>
          </body>

          本文是全套java入門到架構(gòu)師教程之前端開發(fā)部分-jQuery的教學(xué)文檔,如需全套java入門道架構(gòu)師教程請留言或私信

          一)回顧

          break:結(jié)束循環(huán)、流程不再繼續(xù);

          continue:結(jié)束這一次,然后再繼續(xù);

          注意:雖然 continue可以繼續(xù),但是continue后面的內(nèi)容不會被執(zhí)行!

          數(shù)據(jù)類型:1.簡單數(shù)據(jù)類型 2.復(fù)雜數(shù)據(jù)類型

          簡單數(shù)據(jù)類型存儲單值:內(nèi)存的棧—客棧;

          復(fù)雜數(shù)據(jù)類型存儲復(fù)雜值:內(nèi)存的堆—一堆;

          運行方法 string number null undefined Boolean

          簡單類型:var a=1;全部放在棧內(nèi);運算速度快!— 藍(lán)屏— 內(nèi)存被完全占滿了— 重啟

          復(fù)雜數(shù)據(jù)類型:數(shù)組 Object var arr –棧 值 – 堆

          很多學(xué)生的信息,就不能用很多變量來存儲!

          (二)數(shù)組字面量

          VAR ARR=[];

          通過遍歷給arr 賦值,當(dāng)i不連續(xù)的時候,會變成稀疏數(shù)組

          For(var i=0;i <=10;i++){

          }

          (三)函數(shù)

          函數(shù)就是方法,可以理解成一個功能!

          1.函數(shù)的聲明 function 方法名(){

          功能實現(xiàn);

          }

          2.函數(shù)的調(diào)用 方法名();

          (四)函數(shù)的參數(shù)

          參數(shù)分為形式參數(shù)、實際參數(shù)

          Function fn(形式參數(shù)){

          Console.log(形式參數(shù));

          }

          fn(實際參數(shù));

          參數(shù)詳解:

          1.實參比形參多,多余的實參會被忽略;

          2.實參比形參少,undefind; NaN 實參比形參少的時候,不會報錯,但是不會參與運算;

          3.形參與實參參數(shù)名一樣的時候,他們也沒有任何關(guān)系;

          (五)函數(shù)的返回值

          在函數(shù)中運算完成之后,把結(jié)果返回出函數(shù)體,以便后續(xù)使用;

          Function fn(形式參數(shù)){

          Console.log(形式參數(shù));

          Return 結(jié)果;

          }

          計算完成之后,不在方法體中進(jìn)行運算。而是計算完成之后通過return返回之后,再運算;

          Var result=fn(實際參數(shù));

          返回值詳解:

          1.Return后面的內(nèi)容不會再執(zhí)行;

          2.如果函數(shù)沒有返回值,調(diào)用會返回undefined;

          3.一般運算之后,都會把結(jié)果返回出方法體,有利于程序的再次調(diào)用

          (六)函數(shù)的相互調(diào)用

          Function fn2(){

          Console.log(“函數(shù)fn2的調(diào)用的過程”);

          fn1();

          }

          Fn2();

          Function fn1(){

          Console.log(“函數(shù)fn2”);

          }

          比較三個數(shù)的大小?

          (七)重載?

          在其他語言里,函數(shù)名相同,但參數(shù)不同的情況稱之為重載;

          在JS中,函數(shù)名相同,參數(shù)不同也被認(rèn)為是同一函數(shù),JS中沒有重載;

          (八)函數(shù)的兩種聲明方式

          8.1 函數(shù)聲明

          Function fn(){

          }

          Fn();

          8.2 函數(shù)表達(dá)式

          var fn2=function(){

          };

          注意:

          1.函數(shù)表達(dá)式后面要加;

          2.Fn()會函數(shù)聲明內(nèi)部提升的過程;

          3.函數(shù)表達(dá)式不會提升,會提示fn2 is not function;

          (九)匿名函數(shù)

          函數(shù)沒有函數(shù)名的情況,通過變量名來調(diào)用函數(shù),這個函數(shù)不需要名字;

          (十)變量的作用域

          全局變量 局部變量

          全局變量:聲明在最外圍,在整個script中都能使用;

          在函數(shù)內(nèi)部聲明,但是沒有var也是全局變量——但是不要這樣寫!

          var a=10;

          function fn(){

          console.log(a);

          }

          局部變量:在函數(shù)內(nèi)部聲明的變量,只能在內(nèi)部使用;

          var b=20;

          function fn(){

          var d=10;

          }

          (十一)遞歸

          遞歸就是自己調(diào)用自己的方法

          function fn (){

          fn();

          }

          Fn();

          注意:遞歸如果沒有退出條件就是死循環(huán)

          var i=1;

          function fn(){

          i++;

          if(i<10){

          fn();

          }

          }

          fn();

          (十二)回調(diào)函數(shù)

          把函數(shù)當(dāng)做參數(shù)進(jìn)行傳遞的就是回調(diào)函數(shù)!

          function fn1(){

          retrun 100;

          }

          function fn2(fn){

          console.log( fn() + 100);

          }

          Fn2(fn1);

          (十三)對象的方法

          給對象設(shè)置的匿名函數(shù)與調(diào)用

          var person=new Object();

          person.name=“tom”;

          person.age=18;

          person.eat=function(){

          console.log(“吃飯在呢!”);

          }

          Person.eat();

          (十四)對象的字面量

          var stu={};

          stu.name=“tom”;

          stu.age=18;

          stu.sayHi=function (){

          console.log(“HI”);

          }

          var stu2={

          name:tom,

          age:18,

          sayHi=function(){

          console.log(“HI”);

          }

          }

          www.Codecombat.cn


          主站蜘蛛池模板: 国产主播在线一区| 波霸影院一区二区| 亚洲视频一区二区三区四区| 亚洲成av人片一区二区三区 | 日本一区二区三区精品视频| 精品视频一区二区三区免费| 内射女校花一区二区三区| 一区二区三区在线观看视频| 日本精品夜色视频一区二区| 国产一区二区精品久久91| 国产激情精品一区二区三区| 一区二区三区高清在线| 少妇无码AV无码一区| 国产一区二区三区在线影院| 日韩制服国产精品一区| 亚洲AV午夜福利精品一区二区| 性无码免费一区二区三区在线| 亚洲一区二区免费视频| 精品久久综合一区二区| 国产日韩AV免费无码一区二区| 国产激情视频一区二区三区| 亚洲熟妇AV一区二区三区浪潮 | 久久精品国产一区二区三区不卡 | 精品一区二区三区在线成人| 国产无套精品一区二区 | 无码AⅤ精品一区二区三区| 国产在线精品一区二区三区不卡| 精品一区二区三区四区| 日韩视频免费一区二区三区| 国产一区二区三区高清视频 | 精品福利一区3d动漫| 国产午夜精品一区二区三区漫画| 亚洲一区AV无码少妇电影| 亚洲免费一区二区| 日韩在线视频一区| 国产精品福利一区二区久久| 中文字幕国产一区| 视频一区二区在线播放| 国产精品高清一区二区人妖| 日韩免费视频一区二区| 精品国产日韩亚洲一区|