Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use javascript to store functions

2025-01-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article focuses on "how to use javascript storage functions", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to use javascript to store functions.

Background introduction

We all know that to build a front-end page, you need the following three elements:

Element (UI)

Data (Data)

Event / interaction (Event)

In the age of data-driven views, the relationship between these three elements is often shown in the following figure:

The design idea of building a visual platform is often based on the above process. We need to provide an editor environment for users to create views and interactions. The product saved by the end user may be like this:

{"name": "Dooring form", "bgColor": "# 666", "share_url": "http://xxx.cn"," mount_event ": [{" id ":" 123", "func": () = > {/ / initialization logic GamepadHapticActuator () }, "sourcedata": []}], "body": [{"name": "header", "event": [{"id": "123"," type ":" click " "func": () = > {/ / component custom interaction logic showModal () }}]}]}

So here's the problem: we can save json strings (we can serialize them through JSON.stringify), but how do we save functions as well? After saving the function, how can you let js run this function normally when the page is rendered?

Thoughts on the realization Plan

We all know that converting js objects to json can be done with JSON.stringify, but it also has limitations, such as:

Conversion value if there is a toJSON () method, then toJson () defines what value will be serialized

Properties of non-array objects are not guaranteed to appear in serialized strings in a specific order.

The wrapper objects of Boolean values, numbers, and strings are automatically converted to the corresponding original values during serialization.

Undefined, arbitrary functions, and symbol values are ignored during serialization (when they appear in the property values of non-array objects) or converted to null (when they appear in the array). When function and undefined are converted separately, undefined is returned, such as JSON.stringify (function () {}) or JSON.stringify (undefined)

All properties with symbol as the property key are completely ignored, even if they are mandatory in the replacer parameter.

The Date date calls toJSON () to convert it to a string string (the same as Date.toISOString ()), so it is treated as a string

Both NaN and Infinity format values and null are treated as null.

Other types of objects, including Map/Set/WeakMap/WeakSet, serialize only enumerable properties

We can see article 4, if there is a function in the object we serialize, it will be ignored! So in general, we can't save functions with JSON.stringify. Is there any other way?

You may think of first converting the function into a string, then serializing it with JSON.stringify and saving it to the backend, and finally using eval or Function to convert the string into a function when the component is in use. The general process is as follows:

Yes, the ideal is beautiful, but the reality is very.

Next, let's analyze how the key links func2string and string2func are implemented.

Scheme Design of js Storage function

Friends familiar with JSON API may know that JSON.stringify supports three parameters, and the second parameter, replacer, can be a function or an array. As a function, it has two parameters, key and value, both of which are serialized. The function needs to return the value in the JSON string, as shown below:

If a Number is returned, the corresponding string is converted to be added to the JSON string as the attribute value

If a String is returned, the string is added to the JSON string as the attribute value

If a Boolean is returned, then "true" or "false" is added to the JSON string as the property value

If any other object is returned, the object is recursively serialized into a JSON string, and the replacer method is called on each property. Unless the object is a function, this case will not be serialized into JSON characters

If undefined is returned, the property value will not be output in the JSON string

So we can convert the data whose value type is a function in the second function parameter. It is as follows:

Const stringify = (obj) = > {return JSON.stringify (obj, (k, v) = > {if (typeof v = 'function') {return `${v}`} return v})}

In this way, we seem to be able to save the function to the back end. Next let's take a look at how to deserialize json with a functional numeric string.

Because we convert a function to a string, we need to know which strings need to be converted into a function when we reverse parsing. If we don't do anything to the function, we may need human flesh recognition.

The disadvantage of human flesh recognition is that we need to use regularization to extract strings with function characteristics, but there are many ways to write functions, we have to consider a lot of cases, and there is no guarantee that strings with function features must be functions.

So I changed to a simple way to extract the function without writing complex rules, by injecting identifiers when the function is serialized, so that we can know that those strings need to be parsed into functions, as follows:

Stringify: function (obj: any, space: number | string, error: (err: Error | unknown) = > {}) {try {return JSON.stringify (obj, (k, v) = > {if (typeof v = 'function') {return `${this.FUNC_PREFIX} ${v}`} return v} Space)} catch (err) {error & & error (err)}}

This.FUNC_PREFIX is the identifier we define so that we can quickly parse the function when using JSON.parse. JSON.parse also supports the second parameter, which is similar to the second parameter of JSON.stringify. We can convert it as follows:

Parse: function (jsonStr: string, error: (err: Error | unknown) = > {}) {try {return JSON.parse (jsonStr, (key, value) = > {if (value & & typeof value = 'string') {return value.indexOf (this.FUNC_PREFIX) >-1? New Function (`return ${value.replace (this.FUNC_PREFIX,'')} `) (): value} return value})} catch (err) {error & & error (err)}}

New Function can convert a string into a js function. It only accepts string parameters, its optional parameters are the input parameters of the method, and the required parameters are the content of the method body. A visual example:

The content of the function body in our above code:

New Function (`return ${value.replace (this.FUNC_PREFIX,')} `) ()

The reason for return is to restore the original function intact, we can also use eval, but out of public opinion or cautious use.

The above solutions can already achieve the function of front-end storage functions, but in order to be more engineering and robust, we need to do a lot of additional processing and optimization, so that more people can use your library right out of the box.

Last

In order for more people to use this feature directly, I encapsulated the full version of json serialization scheme into a class library.

The supporting features are as follows:

Stringify supports serialization functions based on native JSON.stringify, error callback

Parse supports deserialization function based on native JSON.parse, error callback

FuncParse serializes functions in the js object with one click and leaves the js object type unchanged

The installation is as follows:

# or npm install xijsyarn add xijs

Use:

Import {parser} from 'xijs';const a = {x: 12, b: function () {alert (1)}} const json = parser.stringify (a); const obj = parser.parse (json); / / call method obj.b (); at this point, I believe you have a deeper understanding of "how to use javascript storage functions", you might as well do it! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report