彩世界开奖app官网-彩世界平台官方网址(彩票平台)
做最好的网站
来自 彩世界平台官方网址 2019-11-28 06:09 的文章
当前位置: 彩世界开奖app官网 > 彩世界平台官方网址 > 正文

Prototype源码浅析 String部分之有关indexOf优化_prot

从着力的庐山真面目目本事加强起首,下面是实际的兑现,那生龙活虎段很好了然的: 复制代码 代码如下: { function strip(){ return this.replace.replace; } function include{ return this.indexOf > -1;//split } function startsWith { return this.lastIndexOf === 0; } function endsWith { var d = this.length - pattern.length; return d >= 0 && this.indexOf === d; } function empty() { return this == ''; } function blank() { return /^s*$/.test; } s.strip = String.prototype.trim || strip; s.include = include; s.startsWith = startsWith; s.endsWith = endsWith; s.empty = empty; s.blank = blank; }); 下面的strip在jquery里面是$.trim,况且大大多相近都以trim。这里直接扩展原生原型的正剧之处就显现出来了,因为背后的JS落成中就落实了trim方法,那就画蛇著足了。 复制代码 代码如下: function strip(){ return this.replace.replace; } 这几个中的replace就是trimLeft,replace是trimRight,可是Prototype.String中从不那七个形式。 上边是那风流倜傥有些比较风趣的地点: 那时候看这段的时候,对个中的startsWith和endsWith甚是不解,按理来讲,startsWith用indexOf就足以了,这里却是用的lastIndexOf。后来去翻了刹那间Prototype1.6本子的落到实处: 复制代码 代码如下: function startsWith { return this.indexOf === 0; } function endsWith { var d = this.length - pattern.length; return d >= 0 && this.lastIndexOf === d; } 可知,早先版本中startsWith用的正是indexOf,不过1.7本子改正了startsWith的贯彻。在1.7本子中: startsWith完成中lastIndexOf从后迈入查找,可是源点设置为0,因而,只供给检验初始一回就可以了。 endsWith达成中indexOf早前向后查找,由于字符串长度不定,因而这里总计了意气风发晃尺寸,然后再分明了源点,因而也只须要检查实验结尾三回就能够了。 这里的属性优化之处在于,1.6的实现中,假若最初未有相称,不过indexOf依然会向后查找,直到找到一个非凡的依然字符串结尾,那样就浪费了。比如,对于上边的叁个操作: 'abcdefgabcdefg'.startsWith 在1.6版本和1.7本子的兑现中,未有任何不一样,然则大家转移一下: 'abcdefgabcdefg'.startsWith 在1.6落到实处中,startsWith内部的indexOf操作会在始发的a未有和x相配后,即便还未需求再持续了,然则indexOf依然会继续向后寻找,直到找到相称的‘xesam'也许字符串末尾。 在1.7落实中,startsWith内部的lastIndexOf是反向搜索的,因而在上马的a没有和x相配后,操作就止住了,因为lastIndexOf已经到头了。 这么一相对来讲,若是待检查评定的字符串十分长的话,三种达成方式的功能会有分明的分化。 endsWith的原理也是同大器晚成的。

'abcdefgabcdefg'.startsWith('abc')
在1.6版本和1.7版本的完毕中,未有其他分歧,然则我们转移一下:

escapeHTML :复制代码 代码如下:'

累积到String.prototype中的方法很多,可是综合起来,大约分为上边几类:

function strip(){
return this.replace(/^s /,'').replace(/s $/,'');
}

This is an article

分拣方法名原始技能进步 strip| include |startsWith |endsWith| empty| blank格式camelize | capitalize| underscore| dasherize |inspect 变形toArray| succ |times替换interpolate |sub| scan| truncate | gsubHTML管理stripTags |escapeHTML| unescapeHTML参数系列化toQueryParamsJSON管理unfilterJSON| isJSON| evalJSON| parseJSON脚本管理stripScripts| extractScripts |evalScripts

上边是那大器晚成都部队分可比风趣的地点:

复制代码 代码如下://String对象的静态方法 Object.extend(String, { interpret: function { return value == null ? '' : String; }, specialChar: { 'b': '\b', 't': '\t', 'n': '\n', 'f': '\f', 'r': '\r', '\': '\\' } }); Object.extend(String.prototype, { //内部方法,为gsub和sub函数领头化replacement参数 function prepareReplacement { if (Object.isFunction return replacement; var template = new Template; return function { return template.evaluate }; } //用replacement替换全数适合pattern的字符串 //注意当replacement不为函数时,那之中会有三个递归调用,当中参数pattern会变为Template.pattern //能够参见Template的evaluate方法,这里布局的充裕抢眼,在while循环里的else部分会管理这么些递归调用的结果 function gsub { var result = '', source = this, match; replacement = prepareReplacement; if (Object.isString pattern = RegExp.escape; //假如pattern参数为null恐怕'',用把整个字符串遵照单个字符分割,何况在各种字符的左右增多replacement if (!(pattern.length || pattern.source)) { replacement = replacement; return replacement source.split replacement; } while { //即使source相称pattern if (match = source.match { //收取十二分此前的字符串 result = source.slice; //相配替换 result = String.interpret; //把相配字符之后的部分赋给source,实行下一回相配source = source.slice(match.index match[0].length); } else { //固然source不匹配pattern,则直接把source增多到结果上,并把source置空,停止循环 result = source, source = ''; } } return result; } //基本意思和gsub同样,只然而多叁个count参数,表示要替换三遍 function sub(pattern, replacement, count) { replacement = prepareReplacement; count = Object.isUndefined ? 1 : count; return this.gsub(pattern, function { if return match[0]; return replacement; } //对相符pattern的字符串实行iterator调用 function scan { this.gsub; return String; } //遵照给定长度截断字符串 function truncate { length = length || 30; truncation = Object.isUndefined ? '...' : truncation; return this.length > length ? this.slice(0, length - truncation.length) truncation : String; } //剔除字符串前后空格 function strip() { return this.replace.replace; } //把字符串的html标志剔除 function stripTags() { return this.replace(/|/gi, ''); } //把字符串中的script标识剔除 function stripScripts() { return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); } //获取字符串中的script内容 function extractScripts() { var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); return || []).map { return (scriptTag.match || ['', ''])[1]; }); } //实践字符串中的script内容 function evalScripts() { return this.extractScripts().map { return eval; } //转义HTML内容,举例把'<>&'等独特字符替换来标准的HTML表明情势function escapeHTML() { escapeHTML.text.data = this; return escapeHTML.div.innerHTML; } function unescapeHTML() { var div = document.createElement; div.innerHTML = this.stripTags(); return div.childNodes[0] ? (div.childNodes.length > 1 ? $A.inject('', function { return memo node.nodeValue }) : div.childNodes[0].nodeValue) : ''; } //依照separator参数把字符串分割成查询参数情势 function toQueryParams { var match = this.strip return { }; return match[1].split.inject({ }, function { if ((pair = pair.split { var key = decodeURIComponent; var value = pair.length > 1 ? pair.join : pair[0]; if value = decodeURIComponent; if { if (!Object.isArray hash[key] = [hash[key]]; hash[key].push; } else hash[key] = value; } return hash; }); } function toArray() { return this.split; } //再次来到字符串的字符 function succ() { return this.slice String.fromCharCode(this.charCodeAt; } //拿到重新的字符串 function times { return count < 1 ? '' : new Array; } //把css样式类型的字符串转换来脚本形式 function camelize() { var parts = this.split, len = parts.length; if return parts[0]; var camelized = this.charAt == '-' ? parts[0].charAt parts[0].substring : parts[0]; for (var i = 1; i < len; i ) camelized = parts[i].charAt parts[i].substring; return camelized; } //首字母大写 function capitalize() { return this.charAt this.substring; } //'borderBottomWidth'.underscore(); // -> 'border_bottom_width' function underscore() { return this.gsub.gsub/,'#{1}_); } //'border_bottom_width'.dasherize(); // -> 'border-bottom-width' function dasherize() { return this.gsub; } //Returns a debug-oriented version of the string function inspect { var escapedString = this.gsub(/[x00-x1f\]/, function { var character = String.specialChar[match[0]]; return character ? character : '\u00' match[0].charCodeAt().toPaddedString; if return '"' escapedString.replace '"'; return "'" escapedString.replace "'"; } function toJSON() { return this.inspect; } function unfilterJSON { return this.sub(filter || Prototype.JSONFilter, '#{1}'); } function isJSON() { var str = this; if return false; str = this.replace.replace; return (/^[,:{}[]0-9.- Eaeflnr-u nrt]*$/).test; } //Strips comment delimiters around Ajax JSON or JavaScript responses. This security method is called internally. function evalJSON { var json = this.unfilterJSON(); try { if (!sanitize || json.isJSON return eval; } catch { } throw new SyntaxError('Badly formed JSON string: ' this.inspect; } function include { return this.indexOf > -1; } function startsWith { return this.indexOf === 0; } function endsWith { var d = this.length - pattern.length; return d >= 0 && this.lastIndexOf === d; } function empty() { return this == ''; } function blank() { return /^s*$/.test; } //和Template的evaluate方法相像 function interpolate { return new Template.evaluate; } return { gsub: gsub, sub: sub, scan: scan, truncate: truncate, strip: String.prototype.trim ? String.prototype.trim : strip, stripTags: stripTags, stripScripts: stripScripts, extractScripts: extractScripts, evalScripts: evalScripts, escapeHTML: escapeHTML, unescapeHTML: unescapeHTML, toQueryParams: toQueryParams, parseQuery: toQueryParams, toArray: toArray, succ: succ, times: times, camelize: camelize, capitalize: capitalize, underscore: underscore, dasherize: dasherize, inspect: inspect, toJSON: toJSON, unfilterJSON: unfilterJSON, isJSON: isJSON, evalJSON: evalJSON, include: include, startsWith: startsWith, endsWith: endsWith, empty: empty, blank: blank, interpolate: interpolate }; }); Object.extend(String.prototype.escapeHTML, { div: document.createElement, text: document.createTextNode; String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text); //以下预计是消除浏览器包容难点 if !== '') { String.prototype.escapeHTML = function() { return this.replace.replace.replace; }; } if !== '') { String.prototype.unescapeHTML = function() { return this.stripTags.replace.replace; }; }blank camelize capitalize dasherize empty endsWith escapeHTML evalJSON evalScripts extractScripts gsub include inspect interpolate isJSON parseQuery scan startsWith strip stripScripts stripTags sub succ times toArray toJSON toQueryParams truncate underscore unescapeHTML unfilterJSON 上边只交给一些非同儿戏措施的例证,简单方法就略过了

复制代码 代码如下:

" 'x > 10'.unescapeHTML() // -> 'x > 10' '

分类 方法名 
原始能力增强               strip |  include  |  startsWith  |  endsWith |  empty |  blank
格式 camelize | capitalize |  underscore |  dasherize  | inspect          
变形 toArray |  succ  | times
替换 interpolate  | sub |  scan |  truncate | gsub
HTML处理 stripTags  | escapeHTML |  unescapeHTML
参数序列化 toQueryParams
JSON处理 unfilterJSON |  isJSON |  evalJSON |  parseJSON
脚本处理 stripScripts |  extractScripts  | evalScripts

'.escapeHTML(); // -> "

从核心的原有技术巩固初步,上面是活龙活现的贯彻,那后生可畏段很好通晓的:

Pride & Prejudice

'.unescapeHTML() // -> 'Pride & Prejudice'

evalJSON :

String对象里面包车型客车有多少个方法是为了防守XSS Attack攻击的,有意思味的能够搜一下,下边给出XSS的概念:

Cross-site scripting is a type of computer security vulnerability typically found in web applications which allow code injection by malicious web users into the web pages viewed by other users. 复制代码 代码如下:var person = '{ "name": "瓦奥莱特", "occupation": "character" }'.evalJSON(); person.name; //-> "维尔莉特" person = 'grabUserPassword; //-> SyntaxError: Badly formed JSON string: 'grabUserPassword()' person = '/*-secure-n{"name": "Violet", "occupation": "character"}n*/'.evalJSON() person.name; //-> "维尔莉特" 复制代码 代码如下:'lorem...

'.evalScripts(); // -> [4] '

'.evalScripts(); // -> [4, undefined] (and displays 'hello world!' in the alert dialog)gsub :复制代码 代码如下:var mouse伊芙nts = 'click dblclick mousedown mouseup mouseover mousemove mouseout'; mouseEvents.gsub; // -> 'click, dblclick, mousedown, mouseup, mouseover, mousemove, mouseout' mouseEvents.gsub(/w /, function{return 'on' match[0].capitalize; // -> 'onClick onDblclick onMousedown onMouseup onMouseover onMousemove onMouseout' var markdown = '![a pear] ![an orange]'; markdown.gsub/, function{ return '彩世界平台官方网址 1'; }); // -> '彩世界平台官方网址 2 彩世界平台官方网址 3' //================================================== var fruits = 'apple pear orange'; fruits.sub; // -> 'apple, pear orange' fruits.sub; // -> 'apple, pear orange' fruits.sub; // -> 'apple, pear, orange' fruits.sub(/w /, function{return match[0].capitalize; // -> 'Apple, Pear, orange' var markdown = '![a pear] ![an orange]'; markdown.sub/, function{ return '彩世界平台官方网址 4'; }); // -> '彩世界平台官方网址 5 ![an orange]' markdown.sub/, '彩世界平台官方网址 6'); // -> '彩世界平台官方网址 7 ![an orange]' interpolate() : 复制代码 代码如下: "#{animals} on a #{transport}".interpolate({ animals: "Pigs", transport: "Surfboard" }); //-> "Pigs on a Surfboard" scan() : 复制代码 代码如下: var fruits = []; 'apple, pear & orange'.scan(/w /, function{ fruits.push; fruits.inspect() // -> ['apple', 'pear', 'orange'] times() : 复制代码 代码如下: "echo ".times; //-> "echo echo echo " toQueryParams(): 复制代码 代码如下:'section=blog&id=45'.toQueryParams(); // -> {section: 'blog', id: '45'} 'section=blog;id=45'.toQueryParams(); // -> {section: 'blog', id: '45'} '); // -> {section: 'blog', id: '45'} 'section=blog&tag=javascript&tag=prototype&tag=doc'.toQueryParams(); // -> {section: 'blog', tag:['javascript', 'prototype', 'doc']} 'tag=ruby on rails'.toQueryParams(); // -> {tag: 'ruby on rails'} 'id=45&raw'.toQueryParams(); // -> {id: '45', raw: undefined}

复制代码 代码如下:

This is an article

增加到String.prototype中的方法相当多,但是综合起来,大概分成下边几类:

startsWith完成中lastIndexOf从后迈入查找,可是源点(fromindex卡塔 尔(阿拉伯语:قطر‎设置为0,由此,只必要检验开端二次就足以了。
endsWith实现中indexOf之前向后查找,由于字符串长度不定,由此这里总计了一下长短,然后再鲜明了源点(fromindex卡塔 尔(英语:State of Qatar),由此也只供给检查评定结尾一遍就足以了。

上边的strip在jquery里面是$.trim,何况大多数经常都以trim。这里一向增添原生原型的喜剧之处就显现出来了,因为背后的JS完毕中(比如chrome)就兑现了trim方法,那就冠上加冠了。

那中间的replace(/^s /,'')就是trimLeft,replace(/s $/,'')是trimRight,然则Prototype.String中绝非那五个办法。

'abcdefgabcdefg'.startsWith('xesam')
在1.6兑现中,startsWith内部的indexOf操作会在开头的a未有和x相称后,就算尚未供给再持续了,可是indexOf依旧会继续向后搜索,直到找到相配的‘xesam'大概字符串末尾。
在1.7落到实处中,startsWith内部的lastIndexOf是反向寻觅的(fromIndex=0卡塔 尔(阿拉伯语:قطر‎,因而在开端的a未有和x相称后,操作就止住了,因为lastIndexOf已经深透了。
那样生机勃勃对照,假设待检测的字符串不长的话,两种完成情势的频率会有醒目标界别。
endsWith的规律也是同等的。

function endsWith(pattern) {
var d = this.length - pattern.length;
return d >= 0 && this.lastIndexOf(pattern) === d;
}

function startsWith(pattern) {
return this.indexOf(pattern) === 0;
}

分类 方法名 原始技术巩固 strip | include | startsWith | endsWith | empt...

(function(s){
function strip(){
return this.replace(/^s /,'').replace(/s $/,'');
}
function include(pattern){
return this.indexOf(pattern) > -1;//split
}
function startsWith(pattern) {
return this.lastIndexOf(pattern, 0) === 0;
}
function endsWith(pattern) {
var d = this.length - pattern.length;
return d >= 0 && this.indexOf(pattern, d) === d;
}
function empty() {
return this == '';
}
function blank() {
return /^s*$/.test(this);
}
s.strip = String.prototype.trim || strip;
s.include = include;
s.startsWith = startsWith;
s.endsWith = endsWith;
s.empty = empty;
s.blank = blank;
})(String.prototype);

立即看这段的时候,对里面的startsWith和endsWith甚是不解,按理来讲,startsWith用indexOf就足以了,这里却是用的lastIndexOf。后来去翻了大器晚成晃Prototype1.6版本的兑现:

此地的性格优化之处在于,1.6的得以达成中,假使伊始未有相配(就是startsWith不树立卡塔 尔(阿拉伯语:قطر‎,但是indexOf如故会向后找出,直到找到多少个同盟的照旧字符串结尾,那样就浪费了。举例,对于上面的一个操作:

复制代码 代码如下:

足见,此前版本中startsWith用的正是indexOf,不过1.7版本校勘了startsWith的落实。在1.7本子中:

本文由彩世界开奖app官网发布于彩世界平台官方网址,转载请注明出处:Prototype源码浅析 String部分之有关indexOf优化_prot

关键词: 脚本 源码 之家 Prototype