怎样在手机上刷单赚钱

JavaScript的预编译
JavaScript的预编译
JavaScript
JS一般都是嵌在html页面中使用,以前总认为JS也跟html一样,是完全解释执行,写在前面的代码一定会先执行。然而,事实并非如此。JS的编译和执行过程如下:
在执行之前,会先进行预编译:对function定义的函数对象,会先预编译为活动对象并添加进内存,其值为函数定义本身,如果出现同名的function,后面定义的,会将前面的覆盖;对以var声明的变量,会先为这个变量在内存中分配一个空间,但并不赋值,此时,其值为undefined。
在解释执行阶段:使用function时,会先在内存中编译的活动对象中查找,如果没有,且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找;遇到类似于 var a = ..形式赋值语句时,就为变量a赋值(在赋值前,变量a只是在内存中有一个空间,但值为undefined,所以在赋值前调用,就会报错。)
然后再是一行行执行所有的语句。
下面来看一些例子:
function hello() {
console.log("js");
function hello() {
console.log("javasript");
以上这个例子,尽管从代码上看,第一次调用hello(),是在hello函数重新定义之前,但是因为在执行代码前,会有预编译,而在预编译阶段,后面定义的hello函数将前面定义的hello给覆盖了,所以,第一次调用hello()时,调用到的是覆盖后的hello,当然也就输出的是javascript了。
var f = function() {
console.log("ffff");
function f() {
console.log("FFFF");
以上这个例子,在一开始就调了一次f(),如果完全解释执行,那里在调用前没有定义f(),应该会报错。然而有预编译这个过程,在第一次f()调用之前,就已经预编译了一个名为f的函数,可以输出“FFFF”(我认为其实输出“ffff”的也编译了,但由于其是匿名函数,则在预编译时,只是在内存中占了块空间,并没有把其赋值给任何变量),所以直接调用f(),输出的是“FFFF”。此后,遇到var f = function()… 这句时,将一个输出”ffff”的匿名函数赋值给了f,原来编译出来的f函数被覆盖了,所以在此之后调用时,都是输出为“ffff”。当解释执行再次遇到funcion f()定义时,由于在预编译时已经编译了,在解释执行时,对这些语句就不再作任何操作了。
console.log(c);
var c = 2;
预编译针对的是function定义的对象,对于普通的值或对象并不进行预统计,如以上例子,会输出undefined,因为在预编译阶段,只是看到var c = ..的时候,给c在内存中分配了一块空间,但并没有赋值,其值为undefined
type="application/javascript"&
function g() {
console.log("ggg");
type="application/javascript"&
function f() {
console.log("fff");
以上这个例子是将函数的定义和调用分别用两个script标签包起来,从执行的结果,可以看出,f()调用时,会报错“Uncaught ReferenceError: f is not defined”,而g()调用时,可以正常执行。这是因为JS的预编译和执行是分段进行的。先将第一个script标签中的程序预编译执行完之后,再去预编译第二个script标签中的代码,所以调用f()时,还有没f的定义,则会报错;在预编译执行第二个script标签时,第一个script标签中预编译好的对象不会被回收,本例中,就表示g()的定义依然存在,所以在第二个script标签中调用g(),是可以正常执行的。
以上可以看出,其实都是函数或变量名同名引起的,如果可以保证整个项目中没有同名的函数变量,这些问题基本上很好避免。然而,一个项目可能有很多人在开发,同名的几率非常大,这可如何是好。
请看下集:JavaScript命名空间
我的热门文章
即使是一小步也想与你分享使用预编译话语是预防SQL注入的最佳方式 - SQL当前位置:& &&&使用预编译话语是预防SQL注入的最佳方式使用预编译话语是预防SQL注入的最佳方式&&网友分享于:&&浏览:0次使用预编译语句是预防SQL注入的最佳方式
sql 预编译指的是数据库驱动在发送 sql 语句和参数给 DBMS 之前对 sql 语句进行编译,这样 DBMS 执行 sql 时,就不需要重新编译。
为什么需要预编译
JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译
预编译阶段可以优化 sql 的执行。
预编译之后的 sql 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的sql,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。
预编译语句对象可以重复利用。
把一个 sql 预编译后产生的 PreparedStatement 对象缓存下来,下次对于同一个sql,可以直接使用这个缓存的 PreparedState 对象。
Mybatis中预编译:使用#{}语法,MyBatis会产生PreparedStatement语句中,并且安全的设置PreparedStatement参数,这个过程中MyBatis会进行必要的安全检查和转义。
示例1:执行SQL:Select * from emp where name = #{employeeName}参数:employeeName=&Smith解析后执行的SQL:Select * from emp where name = ?执行SQL:Select * from emp where name = ${employeeName}参数:employeeName传入值为:Smith解析后执行的SQL:Select * from emp where name =Smith
综上所述、${}方式会引发SQL注入的问题、同时也会影响SQL语句的预编译,所以从安全性和性能的角度出发,能使用#{}的情况下就不要使用${}。
1、能使用 #{ } 的地方就用 #{ }
首先这是为了性能考虑的,相同的预编译 sql 可以重复利用。
其次, ${ } 在预编译之前已经被变量替换了,这会存在 sql 注入问题 。例如,如下的 sql,
select * from ${tableName} where name = #{name}
假如,我们的参数 tableName 为
-- ,那么 SQL 动态解析阶段之后,预编译之前的 sql 将变为
select * from user; delete user;
-- 之后的语句将作为注释,不起作用,因此本来的一条查询语句偷偷的包含了一个删除表数据的 SQL!
2、表名作为变量时,必须使用 ${ }
这是因为,表名是字符串,使用 sql 占位符替换字符串时会带上单引号 '' ,这会导致 sql 语法错误,例如:
select * from #{tableName} where name = #{name};
预编译之后的sql 变为:
select * from ? where name = ?;
假设我们传入的参数为 tableName = "user" , name = "ruhua",那么在占位符进行变量替换后,sql 语句变为
select * from 'user' where name='ruhua';
上述 sql 语句是存在语法错误的,表名不能加单引号 '' (注意,反引号 ``是可以的)。
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 1234567891011 Copyright & &&版权所有SDK 跨平台支持常见问题及解决方案实践
作者简介:
李叶,毕业于华中科技大学,现为 LeanCloud Java SDK 负责人。在前端工程化、前端性能方面有丰富的经验,关注 React 及相关技术。
责任编辑:唐小引,技术之路,共同进步。欢迎技术投稿、约稿,给文章纠错,请发送邮件至。
导语:本文主要介绍 SDK 在跨平台支持过程中开发者们经常遇见的问题,以及解决这些问题时用到的工具并总结的一些最佳实践。希望可以为那些对跨平台开发有兴趣的同学提供有价值的帮助。
作为后端云服务提供商,我们在底层通过 REST API 与 WebSocket 提供数据、文件存储、短信、推送、实时消息等服务。还为各个目标平台编写了 SDK 来封装这些 API,在 SDK 中实现客户端状态的持久化,为用户提供更加符合直觉的抽象。一个有趣的现象是越来越多的平台使用的都是 Java:
Web(浏览器/WebView/Windows Universal App/…)
Electron/NW.js
React Native
Cocos2d-x(Java binding)
微信小程序
为什么 SDK 要跨平台?降低成本是最为重要的一大原因。对于用户,提供跨平台的 SDK 可以降低学习与切换成本。并且,随着同构应用以及服务端渲染的流行,对于采用这种方案的用户,跨平台 SDK 可以方便地作为「平台无关」代码进行共享。而对于公司而言,如果能够在多个平台中共享这部分代码,将会减少 SDK 的开发与维护成本。
基于以上前提,我们的目标具体表现为:
使用一套代码;
一致的 API;
各平台提供一致的安装加载方式。
接下来,我们分 API、编译打包、小程序、测试四个部分详细了解 SDK 在跨平台实践中遇到的常见问题及解决方案。
API 平台间的相同点
Java Engine
这些平台都会使用内置或者外部的 Java Engine 来执行 Java 代码。所有属于 ECMA 标准的 API 都是所有平台都支持的,比如 Math、Array、TypedArray、Promise、正则表达式。这倒不是指它们使用的是同一个 Java Engine(事实上存在 V8、SpiderMonkey、JSC、Chakra 等各种实现),得益于 TC39 的存在以及 Babel 的出色表现,我们几乎不需要担心我们的 Java 代码在不同平台上的一致性问题。这也意味着,如果一个第三方库只使用了 ECMA 的 API,那么它一定是跨平台的,我们可以放心使用,一个典型的例子就 lodash。
ECMA 的 API 是语言层面上的,除此之外,各个平台还会根据自己需要解决的问题提供平台特有的 API。比如,其中唯一有委员会(W3C)来制定标准的平台——Web 平台——提供了下面这些 API。
设备 API:地理位置,陀螺仪、电池、MediaCapture;
通讯 API:网络请求、WebSocket、WebRTC、推送;
数据管理 API:文件、本地存储、数据库。
其中 DOM API 在其他平台上都没有,而网络请求 API 在 Node.js 平台上则是完全不同的设计。对于 LeanCloud SDK,我们关心的是实现以下这些功能以及实现所需要用到的 API:
从上表中可以看到平台在设计这些基础能力 API 时,分为三大流派:
客户端平台(Web、React Native、cocos2d-x):(尽可能)内置 W3C 标准 API 的实现;
Node.js API:作为唯一的服务端 Runtime,提供底层的能力,上层实现交给社区(上面说到的 W3C API,几乎都能找到基于 Node.js API 的实现);
微信小程序。
API 的本质是对实现的抽象,SDK 就像一个由 API 调用构成的金字塔,越往上抽象越贴近用户。要跨平台,用户就需要将不同的底层 API 抽象成一个。这里有两种思路,假设我们有两个平台的 API A 与 B:
用 B 实现 A;
分别用 A 与 B 实现 C;
具体到我们的实现:
要想达成只使用一套 codebase 的目标,除了统一的 API 在各平台上的不同实现,还需要在不同的平台上运行对应的代码。我们先来看看有哪些工具能完成这个任务,这里以 WebSocket 为例。
运行时判断
最开始,我们的 SDK 是没有编译打包环节的,在运行时进行平台检测来执行不同的代码。
// src/websocket.js
if(!utils.isNode) { WebSocket = window.WebS} else{ WebSocket = require( 'ws').WebS}
? 随着平台数量增加,文件体积大(这是一个例子,实际上 if else 的内容可能很长);
? 平台检测不可靠,随着平台数量增加难以维护。
为了解决这个问题,我们引入了 webpack 来实现「条件编译」:
// src/websocket.js
if(process.env.PLATFORM === 'Browser') { WebSocket = window.WebS} else{ WebSocket = require( 'ws').WebS} // webpack/browser.js
module.exports = {
// ...plugins: [
newwebpack.EnvironmentPlugin([ "PLATFORM"]) ]}; // package.json:{ "s": { "build:browser": "PLATFORM=Browser webpack --config webpack/browser.js" }}
webpack 后:
if( 'Browser'=== 'Browser') { WebSocket = window.WebS} else{ WebSocket = require( 'ws').WebS}
uglify 后:
varWebSWebSocket= window.WebS
? 现在有多个入口了,怎么告诉平台使用哪个呢?(需要提供一致的加载方式)
? ws 怎么也打包进来了?(因为 bundler 不知道不需要 ws,换句话说,我们需要找到一种方式告知 bundler。)
package browser field spec
可见:/defunctzombie/package-browser-field-spec
// package.json:{ "browser": { "ws": "./src/websocket.js" }}
// src/websocket-browser.jsmodule.exports = window.WebS // src/websocket.jsconstWebSocket = require( 'ws');除了对内告诉 bundler 要如何打包模块,browser field 也用来对外申明浏览器版本的入口:// package.json:{ "main": "./dist/node/index.js", "browser": { "./dist/node/index.js": "./dist/av.js", "ws": "./src/websocket-browser.js" }}作为事实标准,browser 字段得到了市面上几乎所有 bundler 的支持(包括 React Native 内置的 Packager、cocos creator 使用的 browserify,以及 webpack 与 rollup),npm 上众多跨平台的 package 也都是采用了这种申明方式。同样的,我们还有一些 React Native 特有的代码需要在打包时替换。webpack 使用了一种更通用的方式支持了这个特性。// package.json:{ "main": "./dist/node/index.js", "browser": { "./dist/node/index.js": "./dist/av.js", "ws": "./src/websocket.js" }, "react-native": { "./dist/node/index.js": "./dist/av-rn.js", "./src/utils/localstorage.js": "./src/utils/localstorage-rn.js" }} // webpack/react-native.jsmodule.exports = {// ...resolve: { aliasFields: [ 'react-native', 'browser'] }}; 预编译?刚才说到,市面上几乎所有的 bundler 都支持这个标准,bundler 会按照我们的配置正确的使用对应的模块,所以为目标平台编译出一个文件并不是必须的。事实上这样做是有缺点的
无法与其他模块共享代码
无法自动得到依赖模块的 patch
与此同时,预编译的版本也不会自动得到依赖模块的新 bug,并且考虑到很多 bundler 在具体的实现上总有各种各样的问题,所以我们目前依然在每次一发布时都提供了各个平台的预编译版本。至此,我们几乎完成了前面所设定的目标:
我们使用一个 codebase,共享了大部分的代码;
统一使用 npm 安装,使用 require 加载,为不同的平台指定不同的入口;
提供了统一的 API。
直到出现了一位新玩家。小程序带来的新挑战先来看下小程序的架构。在第一部分说到,由于 Web API 抽象层级高、后台硬、现有轮子多,各个平台都倾向于实现 Web API。SDK 大部分时候都是直接调用的 Web API。另一方面,我们也使用了 superagent/axios 等第三方库提供更加易用的 API,并不希望去修改这些第三方库。很自然地,为了适配小程序,最便捷的方案是用小程序的 API 来 polyfill Web API。很快我们就遇到了两个问题:unpolyfillable runtime小程序的 Java 代码在真机上是运行在 JSC / JSCore 上的,但是在开发者工具中,这部分代码是直接运行在浏览器环境中的,是能够使用包括 window、document、 在内的所有 Web API 的。为了保证 IDE 与真机运行环境的一致性,IDE 在编译阶段会在每个文件的 CommonJS wapper 中申明这些变量:define( "app", function(require, module, exports, window,document,frames,self,location,navigator,localStorage,history,Caches,screen,alert,confirm,prompt,,WebSocket,webkit,WeixinJSCore,WeixinJSBridge,Reporter){'use strict'; // SDK codenew(); // thrownewwindow.(); // throw});这意味着即使能够为 global object 增加 Web API,也无法在其他文件中访问到。define( "app", function(require, module, exports, window,/* ... */){'use strict'; // polyfill codewindow= window|| {};window. = require( './.js');try{ = || require( './.js'); } catch(e) {}// SDK codenew();newwindow.();}); 小程序的 API 的抽象层级在 Web API 之上还是以 HTTP 请求为例,小程序的 wx.request API 在开发者工具中是用浏览器中的 实现的。因此小程序的 API 缺少了很多实现 Web API 需要的特性:
Response Headers 无法获得;
不支持上传进度;
不支持 abort;
拿不到 HEADERS_RECEIVED 与 LOADING 等中间状态。
一方面,我们只能在微信小程序中禁用掉 SDK 的一些功能,比如文件上传进度功能。另一方面尽可能去 mock 一些特性或数据来保证现有的基于 Web API 的代码逻辑不会抛异常,比如 getResponseHeade('content-type') 始终返回 'application/json',其他 key 始终返回 ‘’。这些 polyfill 开源在 GitHub - leancloud/weapp-polyfill: Polyfills for w3c API on top of Weapp API。目前我们 polyfill 了以下 API,如果有在小程序中使这些 API 的需求,这个库应该能节省你一些时间。
localStorage
测试 测试是保证 SDK 质量的重要手段,我们使用了 Mocha 作为测试框架,Sinon.js 作为 spy 与 mock 工具,它们都同时支持浏览器与 Node.js。再加上 SDK 提供的 API 是平台无关的,使得我们能够使用一份测试代码分别在浏览器与 Node.js 中运行测试。对于跨平台 SDK,测试流程的自动化是必不可少的。我们使用 travis-ci 来运行 Node.js 的测试,使用 Saucelabs(Selenium)来运行浏览器测试,保证每次提交在我们支持的所有 Node.js 版本与我们支持的所有浏览器中都能通过测试。遗憾的是,对于其他平台,由于工具的缺失,目前并没有良好的测试方案,我们现在也只是在发布之前手动进行冒烟测试。了解最新移动开发、VR/AR 干货技术分享,请关注 mobilehub 微信公众号(ID: mobilehub)。
责任编辑:
声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。js与前端(864)
javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的“预编译阶段”(javascript的预编译是以代码块为范围&script&&/script&,即每遇到一个代码块都会进行& 预编译&执行),了解javascript引擎的执行机理,将有助于在写js代码过程中的思路总结
首先科普下javascript中的两种声明方式,var和function,前者声明的是变量,后者声明的是方法
在预编译中,javascript对这两种声明做出了两种处理方案
  vara = &1&;    //声明变量a
functionb(){    //声明方法b
  alert();
  varc = function(){//声明变量c
    alert();
以上代码块中,a、c为变量赋值,b为函数声明,当执行以上的代码时,首先会进入预编译阶段,对与变量赋值a、c会在内存中开辟一块内存空间并指向变量名,且赋值为undefined
对于函数声明,则同样会进行开辟内存空间,但赋值的对象会将声明的函数赋值给函数名
预编译阶段:(PS:不管代码中声明变量和声明函数的顺序如何,在预编译阶段会先声明变量,再声明函数)
    vara =
    varc =         varb = function(){
      alert();
    } &/script&
&执行阶段:
    a = &1&;
    c = function(){
      alert();
整体执行步骤:
    vara =
    varc =
    varb = function(){
      alert();
    a = &1&;
    c = function(){
      alert();
    vara = &1&;
    functionb(){
      alert(a);
      vara = &2&;
    b();
ps:javascript的预编译
 &&& 一、先预定义变量,再预定义函数
  二、变量的预编译只作声明,不作初始化,初始化在执行时
&  三、function语句定义的函数,不仅声明了函数名,而且函数体也进行了处理
  四、匿名函数不会预编译
function f(){
// 声明函数f
return 1; } alert(f());
var f = function(){
// 定义匿名函数f
return 2; } alert(f());
先预定义了变量f,然后同名函数f()覆盖了变量f,所以第一次输出1;变量的预编译
var f = function(){
// 定义匿名函数f
return 1; }
alert(f());
function f(){
// 声明函数f
return 2; }
alert(f());
先预定义了变量f,然后同名函数f()覆盖了变量f.
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:496066次
积分:10688
积分:10688
排名:第1396名
原创:287篇
转载:1943篇
(36)(172)(194)(52)(5)(149)(32)(85)(164)(258)(112)(24)(403)(199)(1)(10)(76)(283)

我要回帖

更多关于 手机赚钱方法 的文章

 

随机推荐