From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../a_re-introduction_to_javascript/index.html | 959 ++++++++++++++++++++ .../web/javascript/about_javascript/index.html | 59 ++ files/zh-cn/web/javascript/closures/index.html | 409 +++++++++ .../web/javascript/data_structures/index.html | 321 +++++++ .../ecmascript_7_support_in_mozilla/index.html | 82 ++ .../index.html | 309 +++++++ .../equality_comparisons_and_sameness/index.html | 436 +++++++++ files/zh-cn/web/javascript/eventloop/index.html | 159 ++++ .../web/javascript/getting_started/index.html | 293 ++++++ files/zh-cn/web/javascript/guide/about/index.html | 135 +++ .../control_flow_and_error_handling/index.html | 441 +++++++++ .../guide/details_of_the_object_model/index.html | 758 ++++++++++++++++ .../guide/expressions_and_operators/index.html | 984 +++++++++++++++++++++ .../web/javascript/guide/functions/index.html | 662 ++++++++++++++ .../javascript/guide/grammar_and_types/index.html | 705 +++++++++++++++ files/zh-cn/web/javascript/guide/index.html | 135 +++ .../guide/indexed_collections/index.html | 478 ++++++++++ .../web/javascript/guide/introduction/index.html | 147 +++ .../guide/iterators_and_generators/index.html | 200 +++++ .../guide/javascript_overview/index.html | 135 +++ .../javascript/guide/keyed_collections/index.html | 155 ++++ .../guide/loops_and_iteration/index.html | 409 +++++++++ .../javascript/guide/meta_programming/index.html | 264 ++++++ .../zh-cn/web/javascript/guide/modules/index.html | 460 ++++++++++ .../javascript/guide/numbers_and_dates/index.html | 407 +++++++++ .../regular_expressions/assertions/index.html | 263 ++++++ .../regular_expressions/boundaries/index.html | 6 + .../character_classes/index.html | 216 +++++ .../groups_and_ranges/index.html | 164 ++++ .../guide/regular_expressions/index.html | 745 ++++++++++++++++ .../unicode_property_escapes/index.html | 171 ++++ .../\351\207\217\350\257\215/index.html" | 170 ++++ .../javascript/guide/text_formatting/index.html | 252 ++++++ .../web/javascript/guide/using_promises/index.html | 359 ++++++++ .../guide/working_with_objects/index.html | 522 +++++++++++ files/zh-cn/web/javascript/index.html | 129 +++ .../inheritance_and_the_prototype_chain/index.html | 597 +++++++++++++ .../index.html | 361 ++++++++ .../index.html | 436 +++++++++ .../index.html" | 292 ++++++ .../javascript_technologies_overview/index.html | 96 ++ .../web/javascript/language_resources/index.html | 111 +++ .../web/javascript/memory_management/index.html | 181 ++++ .../javascript/new_in_javascript/1.1/index.html | 71 ++ .../javascript/new_in_javascript/1.2/index.html | 89 ++ .../javascript/new_in_javascript/1.3/index.html | 138 +++ .../javascript/new_in_javascript/1.4/index.html | 25 + .../javascript/new_in_javascript/1.5/index.html | 42 + .../javascript/new_in_javascript/1.6/index.html | 35 + .../javascript/new_in_javascript/1.7/index.html | 40 + .../javascript/new_in_javascript/1.8.1/index.html | 29 + .../javascript/new_in_javascript/1.8.5/index.html | 122 +++ .../javascript/new_in_javascript/1.8/index.html | 39 + .../ecmascript_5_support_in_mozilla/index.html | 41 + .../ecmascript_6_support_in_mozilla/index.html | 282 ++++++ .../web/javascript/new_in_javascript/index.html | 99 +++ .../web/javascript/reference/about/index.html | 52 ++ .../reference/classes/class_elements/index.html | 352 ++++++++ .../reference/classes/constructor/index.html | 132 +++ .../reference/classes/extends/index.html | 106 +++ .../web/javascript/reference/classes/index.html | 450 ++++++++++ .../classes/private_class_fields/index.html | 201 +++++ .../javascript/reference/classes/static/index.html | 138 +++ .../deprecated_and_obsolete_features/index.html | 287 ++++++ .../the_legacy_iterator_protocol/index.html | 79 ++ .../reference/errors/already_has_pragma/index.html | 37 + .../errors/array_sort_argument/index.html | 47 + .../reference/errors/bad_octal/index.html | 55 ++ .../reference/errors/bad_radix/index.html | 61 ++ .../reference/errors/bad_regexp_flag/index.html | 104 +++ .../errors/bad_return_or_yield/index.html | 52 ++ .../errors/called_on_incompatible_type/index.html | 63 ++ .../index.html | 56 ++ .../errors/cant_access_property/index.html | 55 ++ .../index.html | 66 ++ .../reference/errors/cant_delete/index.html | 58 ++ .../errors/cant_redefine_property/index.html | 50 ++ .../errors/cyclic_object_value/index.html | 76 ++ .../reference/errors/dead_object/index.html | 49 + .../errors/delete_in_strict_mode/index.html | 69 ++ .../index.html | 76 ++ .../deprecated_expression_closures/index.html | 78 ++ .../reference/errors/deprecated_octal/index.html | 67 ++ .../errors/deprecated_source_map_pragma/index.html | 109 +++ .../errors/deprecated_string_generics/index.html | 104 +++ .../errors/deprecated_tolocaleformat/index.html | 90 ++ .../reference/errors/equal_as_assign/index.html | 52 ++ .../for-each-in_loops_are_deprecated/index.html | 171 ++++ .../reference/errors/getter_only/index.html | 82 ++ .../errors/identifier_after_number/index.html | 48 + .../reference/errors/illegal_character/index.html | 73 ++ .../errors/in_operator_no_object/index.html | 71 ++ .../web/javascript/reference/errors/index.html | 28 + .../errors/invalid_array_length/index.html | 77 ++ .../invalid_assignment_left-hand_side/index.html | 54 ++ .../errors/invalid_const_assignment/index.html | 90 ++ .../reference/errors/invalid_date/index.html | 54 ++ .../errors/invalid_for-in_initializer/index.html | 73 ++ .../errors/invalid_for-of_initializer/index.html | 63 ++ .../index.html | 56 ++ .../reference/errors/is_not_iterable/index.html | 126 +++ .../reference/errors/json_bad_parse/index.html | 111 +++ .../errors/malformed_formal_parameter/index.html | 61 ++ .../reference/errors/malformed_uri/index.html | 65 ++ .../errors/missing_bracket_after_list/index.html | 56 ++ .../missing_colon_after_property_id/index.html | 76 ++ .../missing_curly_after_function_body/index.html | 66 ++ .../missing_curly_after_property_list/index.html | 51 ++ .../errors/missing_formal_parameter/index.html | 80 ++ .../errors/missing_initializer_in_const/index.html | 57 ++ .../missing_name_after_dot_operator/index.html | 67 ++ .../index.html | 42 + .../missing_parenthesis_after_condition/index.html | 69 ++ .../missing_semicolon_before_statement/index.html | 81 ++ .../errors/more_arguments_needed/index.html | 48 + .../errors/negative_repetition_count/index.html | 45 + .../reference/errors/no_non-null_object/index.html | 65 ++ .../reference/errors/no_properties/index.html | 36 + .../reference/errors/no_variable_name/index.html | 83 ++ .../non_configurable_array_element/index.html | 81 ++ .../reference/errors/not_a_codepoint/index.html | 51 ++ .../reference/errors/not_a_constructor/index.html | 95 ++ .../reference/errors/not_a_function/index.html | 167 ++++ .../reference/errors/not_defined/index.html | 66 ++ .../reference/errors/precision_range/index.html | 96 ++ .../errors/property_access_denied/index.html | 45 + .../reference/errors/read-only/index.html | 76 ++ .../errors/redeclared_parameter/index.html | 62 ++ .../index.html | 88 ++ .../errors/reserved_identifier/index.html | 79 ++ .../errors/resulting_string_too_large/index.html | 50 ++ .../reference/errors/stmt_after_return/index.html | 76 ++ .../errors/strict_non_simple_params/index.html | 113 +++ .../reference/errors/too_much_recursion/index.html | 54 ++ .../typed_array_invalid_arguments/index.html | 76 ++ .../reference/errors/undeclared_var/index.html | 68 ++ .../reference/errors/undefined_prop/index.html | 64 ++ .../reference/errors/unexpected_token/index.html | 50 ++ .../reference/errors/unexpected_type/index.html | 65 ++ .../errors/unnamed_function_statement/index.html | 114 +++ .../errors/unterminated_string_literal/index.html | 67 ++ .../reference/errors/var_hides_argument/index.html | 51 ++ .../index.html" | 52 ++ .../functions/arguments/@@iterator/index.html | 72 ++ .../functions/arguments/callee/index.html | 177 ++++ .../functions/arguments/caller/index.html | 47 + .../reference/functions/arguments/index.html | 275 ++++++ .../functions/arguments/length/index.html | 75 ++ .../reference/functions/arrow_functions/index.html | 484 ++++++++++ .../functions/default_parameters/index.html | 220 +++++ .../javascript/reference/functions/get/index.html | 175 ++++ .../web/javascript/reference/functions/index.html | 528 +++++++++++ .../functions/method_definitions/index.html | 220 +++++ .../reference/functions/rest_parameters/index.html | 168 ++++ .../javascript/reference/functions/set/index.html | 135 +++ .../global_objects/aggregateerror/index.html | 106 +++ .../global_objects/array/@@iterator/index.html | 114 +++ .../global_objects/array/@@species/index.html | 78 ++ .../global_objects/array/@@unscopables/index.html | 89 ++ .../global_objects/array/concat/index.html | 158 ++++ .../global_objects/array/copywithin/index.html | 190 ++++ .../global_objects/array/entries/index.html | 154 ++++ .../global_objects/array/every/index.html | 194 ++++ .../reference/global_objects/array/fill/index.html | 153 ++++ .../global_objects/array/filter/index.html | 234 +++++ .../reference/global_objects/array/find/index.html | 200 +++++ .../global_objects/array/findindex/index.html | 165 ++++ .../reference/global_objects/array/flat/index.html | 218 +++++ .../global_objects/array/flatmap/index.html | 149 ++++ .../global_objects/array/foreach/index.html | 384 ++++++++ .../reference/global_objects/array/from/index.html | 258 ++++++ .../global_objects/array/includes/index.html | 185 ++++ .../reference/global_objects/array/index.html | 445 ++++++++++ .../global_objects/array/indexof/index.html | 197 +++++ .../global_objects/array/isarray/index.html | 140 +++ .../reference/global_objects/array/join/index.html | 111 +++ .../reference/global_objects/array/keys/index.html | 77 ++ .../global_objects/array/lastindexof/index.html | 176 ++++ .../global_objects/array/length/index.html | 149 ++++ .../reference/global_objects/array/map/index.html | 343 +++++++ .../global_objects/array/observe/index.html | 92 ++ .../reference/global_objects/array/of/index.html | 99 +++ .../reference/global_objects/array/pop/index.html | 101 +++ .../global_objects/array/prototype/index.html | 178 ++++ .../reference/global_objects/array/push/index.html | 149 ++++ .../global_objects/array/reduce/index.html | 688 ++++++++++++++ .../global_objects/array/reduceright/index.html | 409 +++++++++ .../global_objects/array/reverse/index.html | 141 +++ .../global_objects/array/shift/index.html | 129 +++ .../global_objects/array/slice/index.html | 253 ++++++ .../reference/global_objects/array/some/index.html | 215 +++++ .../reference/global_objects/array/sort/index.html | 265 ++++++ .../global_objects/array/splice/index.html | 165 ++++ .../global_objects/array/tolocalestring/index.html | 177 ++++ .../global_objects/array/tosource/index.html | 40 + .../global_objects/array/tostring/index.html | 80 ++ .../global_objects/array/unobserve/index.html | 86 ++ .../global_objects/array/unshift/index.html | 120 +++ .../global_objects/array/values/index.html | 125 +++ .../arraybuffer/@@species/index.html | 70 ++ .../arraybuffer/bytelength/index.html | 62 ++ .../global_objects/arraybuffer/index.html | 161 ++++ .../global_objects/arraybuffer/isview/index.html | 87 ++ .../arraybuffer/prototype/index.html | 63 ++ .../global_objects/arraybuffer/slice/index.html | 83 ++ .../global_objects/arraybuffer/transfer/index.html | 116 +++ .../global_objects/asyncfunction/index.html | 121 +++ .../asyncfunction/prototype/index.html | 57 ++ .../global_objects/asynciterator/index.html | 119 +++ .../global_objects/atomics/add/index.html | 84 ++ .../global_objects/atomics/and/index.html | 130 +++ .../atomics/compareexchange/index.html | 86 ++ .../global_objects/atomics/exchange/index.html | 85 ++ .../reference/global_objects/atomics/index.html | 151 ++++ .../global_objects/atomics/islockfree/index.html | 69 ++ .../global_objects/atomics/load/index.html | 76 ++ .../global_objects/atomics/notify/index.html | 93 ++ .../reference/global_objects/atomics/or/index.html | 129 +++ .../global_objects/atomics/store/index.html | 77 ++ .../global_objects/atomics/sub/index.html | 82 ++ .../global_objects/atomics/wait/index.html | 95 ++ .../global_objects/atomics/xor/index.html | 126 +++ .../global_objects/bigint/asintn/index.html | 73 ++ .../global_objects/bigint/asuintn/index.html | 72 ++ .../global_objects/bigint/bigint/index.html | 57 ++ .../reference/global_objects/bigint/index.html | 272 ++++++ .../bigint/tolocalestring/index.html | 116 +++ .../global_objects/bigint/tostring/index.html | 91 ++ .../global_objects/bigint/valueof/index.html | 55 ++ .../global_objects/bigint64array/index.html | 173 ++++ .../global_objects/biguint64array/index.html | 164 ++++ .../reference/global_objects/boolean/index.html | 120 +++ .../global_objects/boolean/prototype/index.html | 75 ++ .../global_objects/boolean/tosource/index.html | 59 ++ .../global_objects/boolean/tostring/index.html | 87 ++ .../global_objects/boolean/valueof/index.html | 83 ++ .../global_objects/dataview/buffer/index.html | 64 ++ .../global_objects/dataview/bytelength/index.html | 70 ++ .../global_objects/dataview/byteoffset/index.html | 67 ++ .../global_objects/dataview/getbigint64/index.html | 91 ++ .../dataview/getbiguint64/index.html | 80 ++ .../global_objects/dataview/getfloat32/index.html | 94 ++ .../global_objects/dataview/getfloat64/index.html | 91 ++ .../global_objects/dataview/getint16/index.html | 94 ++ .../global_objects/dataview/getint32/index.html | 91 ++ .../global_objects/dataview/getint8/index.html | 86 ++ .../global_objects/dataview/getuint16/index.html | 94 ++ .../global_objects/dataview/getuint32/index.html | 91 ++ .../global_objects/dataview/getuint8/index.html | 86 ++ .../reference/global_objects/dataview/index.html | 166 ++++ .../global_objects/dataview/prototype/index.html | 102 +++ .../global_objects/dataview/setbigint64/index.html | 84 ++ .../dataview/setbiguint64/index.html | 83 ++ .../global_objects/dataview/setfloat32/index.html | 86 ++ .../global_objects/dataview/setfloat64/index.html | 86 ++ .../global_objects/dataview/setint16/index.html | 86 ++ .../global_objects/dataview/setint32/index.html | 86 ++ .../global_objects/dataview/setint8/index.html | 80 ++ .../global_objects/dataview/setuint16/index.html | 86 ++ .../global_objects/dataview/setuint32/index.html | 86 ++ .../global_objects/dataview/setuint8/index.html | 84 ++ .../global_objects/date/@@toprimitive/index.html | 61 ++ .../reference/global_objects/date/date/index.html | 108 +++ .../global_objects/date/getdate/index.html | 78 ++ .../global_objects/date/getday/index.html | 88 ++ .../global_objects/date/getfullyear/index.html | 89 ++ .../global_objects/date/gethours/index.html | 75 ++ .../global_objects/date/getmilliseconds/index.html | 76 ++ .../global_objects/date/getminutes/index.html | 73 ++ .../global_objects/date/getmonth/index.html | 89 ++ .../global_objects/date/getseconds/index.html | 77 ++ .../global_objects/date/gettime/index.html | 97 ++ .../date/gettimezoneoffset/index.html | 65 ++ .../global_objects/date/getutcdate/index.html | 75 ++ .../global_objects/date/getutcday/index.html | 77 ++ .../global_objects/date/getutcfullyear/index.html | 76 ++ .../global_objects/date/getutchours/index.html | 76 ++ .../date/getutcmilliseconds/index.html | 74 ++ .../global_objects/date/getutcminutes/index.html | 74 ++ .../global_objects/date/getutcmonth/index.html | 76 ++ .../global_objects/date/getutcseconds/index.html | 74 ++ .../global_objects/date/getyear/index.html | 114 +++ .../reference/global_objects/date/index.html | 248 ++++++ .../reference/global_objects/date/now/index.html | 101 +++ .../reference/global_objects/date/parse/index.html | 184 ++++ .../global_objects/date/prototype/index.html | 180 ++++ .../global_objects/date/setdate/index.html | 79 ++ .../global_objects/date/setfullyear/index.html | 81 ++ .../global_objects/date/sethours/index.html | 88 ++ .../global_objects/date/setmilliseconds/index.html | 75 ++ .../global_objects/date/setminutes/index.html | 91 ++ .../global_objects/date/setmonth/index.html | 86 ++ .../global_objects/date/setseconds/index.html | 83 ++ .../global_objects/date/settime/index.html | 80 ++ .../global_objects/date/setutcdate/index.html | 77 ++ .../global_objects/date/setutcfullyear/index.html | 94 ++ .../global_objects/date/setutchours/index.html | 94 ++ .../date/setutcmilliseconds/index.html | 84 ++ .../global_objects/date/setutcminutes/index.html | 92 ++ .../global_objects/date/setutcmonth/index.html | 90 ++ .../global_objects/date/setutcseconds/index.html | 92 ++ .../global_objects/date/setyear/index.html | 72 ++ .../global_objects/date/todatestring/index.html | 72 ++ .../global_objects/date/togmtstring/index.html | 67 ++ .../global_objects/date/toisostring/index.html | 89 ++ .../global_objects/date/tojson/index.html | 73 ++ .../date/tolocaledatestring/index.html | 155 ++++ .../global_objects/date/tolocaleformat/index.html | 73 ++ .../global_objects/date/tolocalestring/index.html | 161 ++++ .../date/tolocaletimestring/index.html | 151 ++++ .../global_objects/date/tosource/index.html | 50 ++ .../global_objects/date/tostring/index.html | 90 ++ .../global_objects/date/totimestring/index.html | 73 ++ .../global_objects/date/toutcstring/index.html | 76 ++ .../reference/global_objects/date/utc/index.html | 104 +++ .../global_objects/date/valueof/index.html | 86 ++ .../reference/global_objects/decodeuri/index.html | 121 +++ .../global_objects/decodeuricomponent/index.html | 150 ++++ .../reference/global_objects/encodeuri/index.html | 170 ++++ .../global_objects/encodeuricomponent/index.html | 144 +++ .../global_objects/error/columnnumber/index.html | 81 ++ .../global_objects/error/filename/index.html | 85 ++ .../reference/global_objects/error/index.html | 257 ++++++ .../global_objects/error/linenumber/index.html | 54 ++ .../global_objects/error/message/index.html | 110 +++ .../reference/global_objects/error/name/index.html | 110 +++ .../global_objects/error/prototype/index.html | 161 ++++ .../global_objects/error/stack/index.html | 126 +++ .../global_objects/error/tosource/index.html | 53 ++ .../global_objects/error/tostring/index.html | 129 +++ .../reference/global_objects/escape/index.html | 126 +++ .../reference/global_objects/eval/index.html | 319 +++++++ .../reference/global_objects/evalerror/index.html | 116 +++ .../global_objects/evalerror/prototype/index.html | 84 ++ .../global_objects/finalizationregistry/index.html | 153 ++++ .../global_objects/float32array/index.html | 261 ++++++ .../global_objects/float64array/index.html | 259 ++++++ .../global_objects/function/apply/index.html | 219 +++++ .../global_objects/function/arguments/index.html | 125 +++ .../global_objects/function/arity/index.html | 16 + .../global_objects/function/bind/index.html | 324 +++++++ .../global_objects/function/call/index.html | 174 ++++ .../global_objects/function/caller/index.html | 69 ++ .../global_objects/function/displayname/index.html | 121 +++ .../reference/global_objects/function/index.html | 156 ++++ .../global_objects/function/isgenerator/index.html | 40 + .../global_objects/function/length/index.html | 89 ++ .../global_objects/function/name/index.html | 219 +++++ .../global_objects/function/prototype/index.html | 138 +++ .../global_objects/function/tosource/index.html | 49 + .../global_objects/function/tostring/index.html | 230 +++++ .../reference/global_objects/generator/index.html | 142 +++ .../global_objects/generator/next/index.html | 165 ++++ .../global_objects/generator/return/index.html | 99 +++ .../global_objects/generator/throw/index.html | 142 +++ .../global_objects/generatorfunction/index.html | 113 +++ .../generatorfunction/prototype/index.html | 64 ++ .../reference/global_objects/globalthis/index.html | 92 ++ .../javascript/reference/global_objects/index.html | 208 +++++ .../reference/global_objects/infinity/index.html | 57 ++ .../reference/global_objects/int16array/index.html | 254 ++++++ .../reference/global_objects/int32array/index.html | 259 ++++++ .../reference/global_objects/int8array/index.html | 258 ++++++ .../global_objects/internalerror/index.html | 123 +++ .../global_objects/intl/collator/index.html | 177 ++++ .../global_objects/intl/datetimeformat/index.html | 286 ++++++ .../intl/datetimeformat/prototype/index.html | 119 +++ .../global_objects/intl/displaynames/index.html | 28 + .../intl/getcanonicallocales/index.html | 72 ++ .../reference/global_objects/intl/index.html | 132 +++ .../global_objects/intl/listformat/index.html | 115 +++ .../global_objects/intl/locale/index.html | 105 +++ .../intl/numberformat/format/index.html | 92 ++ .../global_objects/intl/numberformat/index.html | 247 ++++++ .../global_objects/intl/pluralrules/index.html | 150 ++++ .../intl/relativetimeformat/index.html | 165 ++++ .../reference/global_objects/isfinite/index.html | 107 +++ .../reference/global_objects/isnan/index.html | 192 ++++ .../reference/global_objects/iterator/index.html | 188 ++++ .../reference/global_objects/json/index.html | 203 +++++ .../reference/global_objects/json/parse/index.html | 224 +++++ .../global_objects/json/stringify/index.html | 267 ++++++ .../global_objects/map/@@iterator/index.html | 101 +++ .../global_objects/map/@@species/index.html | 67 ++ .../global_objects/map/@@tostringtag/index.html | 95 ++ .../reference/global_objects/map/clear/index.html | 76 ++ .../reference/global_objects/map/delete/index.html | 83 ++ .../global_objects/map/entries/index.html | 72 ++ .../global_objects/map/foreach/index.html | 109 +++ .../reference/global_objects/map/get/index.html | 81 ++ .../reference/global_objects/map/has/index.html | 120 +++ .../reference/global_objects/map/index.html | 340 +++++++ .../reference/global_objects/map/keys/index.html | 79 ++ .../reference/global_objects/map/map/index.html | 57 ++ .../global_objects/map/prototype/index.html | 130 +++ .../reference/global_objects/map/set/index.html | 96 ++ .../reference/global_objects/map/size/index.html | 77 ++ .../reference/global_objects/map/values/index.html | 112 +++ .../reference/global_objects/math/abs/index.html | 125 +++ .../reference/global_objects/math/acos/index.html | 115 +++ .../reference/global_objects/math/asin/index.html | 114 +++ .../reference/global_objects/math/asinh/index.html | 87 ++ .../reference/global_objects/math/atan/index.html | 110 +++ .../reference/global_objects/math/atan2/index.html | 140 +++ .../reference/global_objects/math/atanh/index.html | 132 +++ .../reference/global_objects/math/cbrt/index.html | 140 +++ .../reference/global_objects/math/ceil/index.html | 164 ++++ .../reference/global_objects/math/clz32/index.html | 169 ++++ .../reference/global_objects/math/cos/index.html | 106 +++ .../reference/global_objects/math/cosh/index.html | 130 +++ .../reference/global_objects/math/e/index.html | 99 +++ .../reference/global_objects/math/exp/index.html | 105 +++ .../reference/global_objects/math/expm1/index.html | 119 +++ .../reference/global_objects/math/floor/index.html | 222 +++++ .../global_objects/math/fround/index.html | 154 ++++ .../reference/global_objects/math/hypot/index.html | 118 +++ .../reference/global_objects/math/imul/index.html | 141 +++ .../reference/global_objects/math/index.html | 187 ++++ .../reference/global_objects/math/ln10/index.html | 99 +++ .../reference/global_objects/math/ln2/index.html | 99 +++ .../reference/global_objects/math/log/index.html | 139 +++ .../reference/global_objects/math/log10/index.html | 113 +++ .../global_objects/math/log10e/index.html | 99 +++ .../reference/global_objects/math/log1p/index.html | 116 +++ .../reference/global_objects/math/log2/index.html | 113 +++ .../reference/global_objects/math/log2e/index.html | 99 +++ .../reference/global_objects/math/max/index.html | 99 +++ .../reference/global_objects/math/min/index.html | 155 ++++ .../reference/global_objects/math/pi/index.html | 115 +++ .../reference/global_objects/math/pow/index.html | 78 ++ .../global_objects/math/random/index.html | 94 ++ .../reference/global_objects/math/round/index.html | 356 ++++++++ .../reference/global_objects/math/sign/index.html | 152 ++++ .../reference/global_objects/math/sin/index.html | 80 ++ .../reference/global_objects/math/sinh/index.html | 123 +++ .../reference/global_objects/math/sqrt/index.html | 81 ++ .../global_objects/math/sqrt1_2/index.html | 100 +++ .../reference/global_objects/math/sqrt2/index.html | 96 ++ .../reference/global_objects/math/tan/index.html | 107 +++ .../reference/global_objects/math/tanh/index.html | 85 ++ .../reference/global_objects/math/trunc/index.html | 116 +++ .../index.html" | 91 ++ .../reference/global_objects/nan/index.html | 68 ++ .../reference/global_objects/null/index.html | 93 ++ .../global_objects/number/epsilon/index.html | 114 +++ .../reference/global_objects/number/index.html | 195 ++++ .../global_objects/number/isfinite/index.html | 89 ++ .../global_objects/number/isinteger/index.html | 92 ++ .../global_objects/number/isnan/index.html | 102 +++ .../global_objects/number/issafeinteger/index.html | 86 ++ .../number/max_safe_integer/index.html | 105 +++ .../global_objects/number/max_value/index.html | 115 +++ .../number/min_safe_integer/index.html | 58 ++ .../global_objects/number/min_value/index.html | 99 +++ .../reference/global_objects/number/nan/index.html | 105 +++ .../number/negative_infinity/index.html | 112 +++ .../global_objects/number/number/index.html | 58 ++ .../global_objects/number/parsefloat/index.html | 109 +++ .../global_objects/number/parseint/index.html | 82 ++ .../number/positive_infinity/index.html | 130 +++ .../global_objects/number/prototype/index.html | 131 +++ .../global_objects/number/toexponential/index.html | 142 +++ .../global_objects/number/tofixed/index.html | 115 +++ .../global_objects/number/tointeger/index.html | 97 ++ .../number/tolocalestring/index.html | 165 ++++ .../global_objects/number/toprecision/index.html | 133 +++ .../global_objects/number/tosource/index.html | 80 ++ .../global_objects/number/tostring/index.html | 149 ++++ .../global_objects/number/valueof/index.html | 122 +++ .../object/__definegetter__/index.html | 107 +++ .../object/__definesetter__/index.html | 92 ++ .../object/__lookupgetter__/index.html | 121 +++ .../object/__lookupsetter__/index.html | 139 +++ .../global_objects/object/assign/index.html | 321 +++++++ .../global_objects/object/constructor/index.html | 235 +++++ .../global_objects/object/count/index.html | 88 ++ .../global_objects/object/create/index.html | 227 +++++ .../object/defineproperties/index.html | 183 ++++ .../object/defineproperty/index.html | 545 ++++++++++++ .../global_objects/object/entries/index.html | 134 +++ .../global_objects/object/eval/index.html | 85 ++ .../global_objects/object/freeze/index.html | 206 +++++ .../global_objects/object/fromentries/index.html | 105 +++ .../global_objects/object/getnotifier/index.html | 93 ++ .../object/getownpropertydescriptor/index.html | 147 +++ .../object/getownpropertydescriptors/index.html | 87 ++ .../object/getownpropertynames/index.html | 169 ++++ .../object/getownpropertysymbols/index.html | 85 ++ .../object/getprototypeof/index.html | 137 +++ .../object/hasownproperty/index.html | 168 ++++ .../reference/global_objects/object/index.html | 183 ++++ .../reference/global_objects/object/is/index.html | 150 ++++ .../global_objects/object/isextensible/index.html | 144 +++ .../global_objects/object/isfrozen/index.html | 153 ++++ .../global_objects/object/isprototypeof/index.html | 171 ++++ .../global_objects/object/issealed/index.html | 124 +++ .../global_objects/object/keys/index.html | 158 ++++ .../global_objects/object/nosuchmethod/index.html | 208 +++++ .../global_objects/object/object/index.html | 80 ++ .../global_objects/object/observe/index.html | 160 ++++ .../global_objects/object/parent/index.html | 43 + .../object/preventextensions/index.html | 131 +++ .../object/propertyisenumerable/index.html | 146 +++ .../global_objects/object/proto/index.html | 142 +++ .../global_objects/object/prototype/index.html | 194 ++++ .../global_objects/object/seal/index.html | 151 ++++ .../object/setprototypeof/index.html | 233 +++++ .../object/tolocalestring/index.html | 80 ++ .../global_objects/object/tosource/index.html | 128 +++ .../global_objects/object/tostring/index.html | 139 +++ .../global_objects/object/unobserve/index.html | 133 +++ .../global_objects/object/unwatch/index.html | 105 +++ .../global_objects/object/valueof/index.html | 208 +++++ .../global_objects/object/values/index.html | 113 +++ .../global_objects/object/watch/index.html | 201 +++++ .../global_objects/parallelarray/index.html | 53 ++ .../reference/global_objects/parsefloat/index.html | 123 +++ .../reference/global_objects/parseint/index.html | 227 +++++ .../global_objects/promise/all/index.html | 224 +++++ .../global_objects/promise/allsettled/index.html | 73 ++ .../global_objects/promise/any/index.html | 153 ++++ .../global_objects/promise/catch/index.html | 156 ++++ .../global_objects/promise/finally/index.html | 101 +++ .../reference/global_objects/promise/index.html | 311 +++++++ .../global_objects/promise/promise/index.html | 73 ++ .../global_objects/promise/prototype/index.html | 115 +++ .../global_objects/promise/race/index.html | 138 +++ .../global_objects/promise/reject/index.html | 78 ++ .../global_objects/promise/resolve/index.html | 158 ++++ .../global_objects/promise/then/index.html | 304 +++++++ .../global_objects/proxy/handler/apply/index.html | 117 +++ .../proxy/handler/construct/index.html | 130 +++ .../proxy/handler/defineproperty/index.html | 181 ++++ .../proxy/handler/deleteproperty/index.html | 149 ++++ .../global_objects/proxy/handler/get/index.html | 177 ++++ .../handler/getownpropertydescriptor/index.html | 168 ++++ .../proxy/handler/getprototypeof/index.html | 141 +++ .../global_objects/proxy/handler/has/index.html | 176 ++++ .../global_objects/proxy/handler/index.html | 76 ++ .../proxy/handler/isextensible/index.html | 123 +++ .../proxy/handler/ownkeys/index.html | 193 ++++ .../proxy/handler/preventextensions/index.html | 120 +++ .../global_objects/proxy/handler/set/index.html | 125 +++ .../proxy/handler/setprototypeof/index.html | 124 +++ .../reference/global_objects/proxy/index.html | 435 +++++++++ .../global_objects/proxy/proxy/index.html | 118 +++ .../global_objects/proxy/revocable/index.html | 89 ++ .../reference/global_objects/rangeerror/index.html | 163 ++++ .../global_objects/rangeerror/prototype/index.html | 88 ++ .../global_objects/referenceerror/index.html | 168 ++++ .../referenceerror/prototype/index.html | 92 ++ .../global_objects/reflect/apply/index.html | 101 +++ .../global_objects/reflect/construct/index.html | 189 ++++ .../reflect/defineproperty/index.html | 87 ++ .../reflect/deleteproperty/index.html | 134 +++ .../global_objects/reflect/get/index.html | 90 ++ .../reflect/getownpropertydescriptor/index.html | 139 +++ .../reflect/getprototypeof/index.html | 84 ++ .../global_objects/reflect/has/index.html | 133 +++ .../reference/global_objects/reflect/index.html | 106 +++ .../global_objects/reflect/isextensible/index.html | 147 +++ .../global_objects/reflect/ownkeys/index.html | 91 ++ .../reflect/preventextensions/index.html | 93 ++ .../global_objects/reflect/set/index.html | 98 ++ .../reflect/setprototypeof/index.html | 78 ++ .../index.html" | 134 +++ .../global_objects/regexp/@@match/index.html | 109 +++ .../global_objects/regexp/@@matchall/index.html | 89 ++ .../global_objects/regexp/@@replace/index.html | 120 +++ .../global_objects/regexp/@@search/index.html | 153 ++++ .../global_objects/regexp/@@species/index.html | 111 +++ .../global_objects/regexp/@@split/index.html | 151 ++++ .../global_objects/regexp/compile/index.html | 131 +++ .../global_objects/regexp/dotall/index.html | 47 + .../global_objects/regexp/exec/index.html | 199 +++++ .../global_objects/regexp/flags/index.html | 114 +++ .../global_objects/regexp/global/index.html | 107 +++ .../global_objects/regexp/ignorecase/index.html | 107 +++ .../reference/global_objects/regexp/index.html | 269 ++++++ .../global_objects/regexp/input/index.html | 99 +++ .../global_objects/regexp/lastindex/index.html | 128 +++ .../global_objects/regexp/lastmatch/index.html | 98 ++ .../global_objects/regexp/lastparen/index.html | 98 ++ .../global_objects/regexp/leftcontext/index.html | 98 ++ .../global_objects/regexp/multiline/index.html | 108 +++ .../reference/global_objects/regexp/n/index.html | 110 +++ .../global_objects/regexp/prototype/index.html | 152 ++++ .../global_objects/regexp/regexp/index.html | 109 +++ .../global_objects/regexp/rightcontext/index.html | 98 ++ .../global_objects/regexp/source/index.html | 109 +++ .../global_objects/regexp/sticky/index.html | 86 ++ .../global_objects/regexp/test/index.html | 128 +++ .../global_objects/regexp/tosource/index.html | 44 + .../global_objects/regexp/tostring/index.html | 106 +++ .../global_objects/regexp/unicode/index.html | 112 +++ .../global_objects/set/@@iterator/index.html | 81 ++ .../global_objects/set/@@species/index.html | 61 ++ .../reference/global_objects/set/add/index.html | 77 ++ .../reference/global_objects/set/clear/index.html | 120 +++ .../reference/global_objects/set/delete/index.html | 120 +++ .../global_objects/set/entries/index.html | 113 +++ .../global_objects/set/foreach/index.html | 145 +++ .../reference/global_objects/set/has/index.html | 127 +++ .../reference/global_objects/set/index.html | 273 ++++++ .../reference/global_objects/set/set/index.html | 73 ++ .../reference/global_objects/set/size/index.html | 75 ++ .../reference/global_objects/set/values/index.html | 70 ++ .../sharedarraybuffer/bytelength/index.html | 53 ++ .../global_objects/sharedarraybuffer/index.html | 144 +++ .../sharedarraybuffer/prototype/index.html | 62 ++ .../sharedarraybuffer/slice/index.html | 76 ++ .../global_objects/string/@@iterator/index.html | 137 +++ .../global_objects/string/anchor/index.html | 136 +++ .../reference/global_objects/string/big/index.html | 123 +++ .../global_objects/string/blink/index.html | 119 +++ .../global_objects/string/bold/index.html | 119 +++ .../global_objects/string/charat/index.html | 280 ++++++ .../global_objects/string/charcodeat/index.html | 161 ++++ .../global_objects/string/codepointat/index.html | 173 ++++ .../global_objects/string/concat/index.html | 83 ++ .../global_objects/string/endswith/index.html | 98 ++ .../global_objects/string/fixed/index.html | 117 +++ .../global_objects/string/fontcolor/index.html | 141 +++ .../global_objects/string/fontsize/index.html | 130 +++ .../global_objects/string/fromcharcode/index.html | 91 ++ .../global_objects/string/fromcodepoint/index.html | 144 +++ .../global_objects/string/includes/index.html | 111 +++ .../reference/global_objects/string/index.html | 357 ++++++++ .../global_objects/string/indexof/index.html | 181 ++++ .../global_objects/string/italics/index.html | 109 +++ .../global_objects/string/lastindexof/index.html | 162 ++++ .../global_objects/string/length/index.html | 135 +++ .../global_objects/string/link/index.html | 76 ++ .../global_objects/string/localecompare/index.html | 185 ++++ .../global_objects/string/match/index.html | 215 +++++ .../global_objects/string/matchall/index.html | 135 +++ .../global_objects/string/normalize/index.html | 231 +++++ .../global_objects/string/padend/index.html | 100 +++ .../global_objects/string/padstart/index.html | 102 +++ .../global_objects/string/prototype/index.html | 186 ++++ .../global_objects/string/quote/index.html | 116 +++ .../reference/global_objects/string/raw/index.html | 113 +++ .../global_objects/string/repeat/index.html | 124 +++ .../global_objects/string/replace/index.html | 317 +++++++ .../global_objects/string/replaceall/index.html | 171 ++++ .../global_objects/string/search/index.html | 87 ++ .../global_objects/string/slice/index.html | 122 +++ .../global_objects/string/small/index.html | 119 +++ .../global_objects/string/split/index.html | 213 +++++ .../global_objects/string/startswith/index.html | 97 ++ .../global_objects/string/strike/index.html | 116 +++ .../reference/global_objects/string/sub/index.html | 119 +++ .../global_objects/string/substr/index.html | 166 ++++ .../global_objects/string/substring/index.html | 194 ++++ .../reference/global_objects/string/sup/index.html | 118 +++ .../string/tolocalelowercase/index.html | 145 +++ .../string/tolocaleuppercase/index.html | 91 ++ .../global_objects/string/tolowercase/index.html | 136 +++ .../global_objects/string/tosource/index.html | 91 ++ .../global_objects/string/tostring/index.html | 124 +++ .../global_objects/string/touppercase/index.html | 87 ++ .../global_objects/string/trim/index.html | 103 +++ .../global_objects/string/trimleft/index.html | 122 +++ .../global_objects/string/trimright/index.html | 84 ++ .../global_objects/string/valueof/index.html | 58 ++ .../global_objects/symbol/@@toprimitive/index.html | 55 ++ .../global_objects/symbol/asynciterator/index.html | 76 ++ .../global_objects/symbol/description/index.html | 73 ++ .../reference/global_objects/symbol/for/index.html | 154 ++++ .../global_objects/symbol/hasinstance/index.html | 59 ++ .../reference/global_objects/symbol/index.html | 227 +++++ .../symbol/isconcatspreadable/index.html | 97 ++ .../global_objects/symbol/iterator/index.html | 94 ++ .../global_objects/symbol/keyfor/index.html | 115 +++ .../global_objects/symbol/match/index.html | 78 ++ .../global_objects/symbol/matchall/index.html | 65 ++ .../global_objects/symbol/prototype/index.html | 66 ++ .../global_objects/symbol/replace/index.html | 52 ++ .../global_objects/symbol/search/index.html | 113 +++ .../global_objects/symbol/species/index.html | 73 ++ .../global_objects/symbol/split/index.html | 117 +++ .../global_objects/symbol/toprimitive/index.html | 87 ++ .../global_objects/symbol/tosource/index.html | 93 ++ .../global_objects/symbol/tostring/index.html | 116 +++ .../global_objects/symbol/tostringtag/index.html | 129 +++ .../global_objects/symbol/unscopables/index.html | 89 ++ .../global_objects/symbol/valueof/index.html | 106 +++ .../global_objects/syntaxerror/index.html | 171 ++++ .../syntaxerror/prototype/index.html | 132 +++ .../typedarray/@@iterator/index.html | 125 +++ .../global_objects/typedarray/@@species/index.html | 126 +++ .../global_objects/typedarray/buffer/index.html | 106 +++ .../typedarray/bytelength/index.html | 113 +++ .../typedarray/byteoffset/index.html | 110 +++ .../typedarray/bytes_per_element/index.html | 115 +++ .../typedarray/copywithin/index.html | 128 +++ .../global_objects/typedarray/entries/index.html | 124 +++ .../global_objects/typedarray/every/index.html | 144 +++ .../global_objects/typedarray/fill/index.html | 134 +++ .../global_objects/typedarray/filter/index.html | 145 +++ .../global_objects/typedarray/find/index.html | 148 ++++ .../global_objects/typedarray/findindex/index.html | 188 ++++ .../global_objects/typedarray/foreach/index.html | 111 +++ .../global_objects/typedarray/from/index.html | 183 ++++ .../global_objects/typedarray/includes/index.html | 122 +++ .../reference/global_objects/typedarray/index.html | 307 +++++++ .../global_objects/typedarray/indexof/index.html | 132 +++ .../global_objects/typedarray/join/index.html | 128 +++ .../global_objects/typedarray/keys/index.html | 128 +++ .../typedarray/lastindexof/index.html | 130 +++ .../global_objects/typedarray/length/index.html | 113 +++ .../global_objects/typedarray/map/index.html | 151 ++++ .../global_objects/typedarray/name/index.html | 117 +++ .../global_objects/typedarray/of/index.html | 138 +++ .../global_objects/typedarray/prototype/index.html | 171 ++++ .../global_objects/typedarray/reduce/index.html | 137 +++ .../typedarray/reduceright/index.html | 144 +++ .../global_objects/typedarray/reverse/index.html | 106 +++ .../global_objects/typedarray/set/index.html | 131 +++ .../global_objects/typedarray/slice/index.html | 104 +++ .../global_objects/typedarray/some/index.html | 121 +++ .../global_objects/typedarray/sort/index.html | 126 +++ .../global_objects/typedarray/subarray/index.html | 104 +++ .../typedarray/tolocalestring/index.html | 78 ++ .../global_objects/typedarray/tostring/index.html | 114 +++ .../global_objects/typedarray/values/index.html | 126 +++ .../reference/global_objects/typeerror/index.html | 133 +++ .../global_objects/typeerror/prototype/index.html | 93 ++ .../global_objects/uint16array/index.html | 160 ++++ .../global_objects/uint32array/index.html | 176 ++++ .../reference/global_objects/uint8array/index.html | 193 ++++ .../global_objects/uint8clampedarray/index.html | 280 ++++++ .../reference/global_objects/undefined/index.html | 138 +++ .../reference/global_objects/unescape/index.html | 84 ++ .../reference/global_objects/uneval/index.html | 68 ++ .../reference/global_objects/urierror/index.html | 136 +++ .../global_objects/urierror/prototype/index.html | 82 ++ .../global_objects/weakmap/clear/index.html | 104 +++ .../global_objects/weakmap/delete/index.html | 108 +++ .../global_objects/weakmap/get/index.html | 120 +++ .../global_objects/weakmap/has/index.html | 123 +++ .../reference/global_objects/weakmap/index.html | 159 ++++ .../global_objects/weakmap/prototype/index.html | 137 +++ .../global_objects/weakmap/set/index.html | 89 ++ .../global_objects/weakref/deref/index.html | 69 ++ .../reference/global_objects/weakref/index.html | 144 +++ .../global_objects/weakset/add/index.html | 121 +++ .../global_objects/weakset/clear/index.html | 94 ++ .../global_objects/weakset/delete/index.html | 117 +++ .../global_objects/weakset/has/index.html | 118 +++ .../reference/global_objects/weakset/index.html | 148 ++++ .../global_objects/weakset/prototype/index.html | 114 +++ .../global_objects/webassembly/compile/index.html | 101 +++ .../webassembly/compileerror/index.html | 114 +++ .../webassembly/compilestreaming/index.html | 77 ++ .../global_objects/webassembly/global/index.html | 107 +++ .../global_objects/webassembly/index.html | 106 +++ .../global_objects/webassembly/instance/index.html | 89 ++ .../webassembly/instantiate/index.html | 175 ++++ .../webassembly/instantiatestreaming/index.html | 85 ++ .../global_objects/webassembly/memory/index.html | 112 +++ .../global_objects/webassembly/module/index.html | 87 ++ .../webassembly/runtimeerror/index.html | 111 +++ .../global_objects/webassembly/table/index.html | 130 +++ .../global_objects/webassembly/validate/index.html | 75 ++ files/zh-cn/web/javascript/reference/index.html | 423 +++++++++ .../reference/iteration_protocols/index.html | 390 ++++++++ .../reference/lexical_grammar/index.html | 572 ++++++++++++ .../operators/addition_assignment/index.html | 74 ++ .../operators/arithmetic_operators/index.html | 301 +++++++ .../operators/array_comprehensions/index.html | 157 ++++ .../reference/operators/assignment/index.html | 62 ++ .../operators/assignment_operators/index.html | 412 +++++++++ .../index.html" | 98 ++ .../reference/operators/await/index.html | 158 ++++ .../operators/bitwise_and_assignment/index.html | 59 ++ .../reference/operators/bitwise_not/index.html | 100 +++ .../operators/bitwise_operators/index.html | 755 ++++++++++++++++ .../reference/operators/bitwise_or/index.html | 108 +++ .../operators/bitwise_or_assignment/index.html | 57 ++ .../reference/operators/bitwise_xor/index.html | 108 +++ .../operators/bitwise_xor_assignment/index.html | 65 ++ .../reference/operators/class/index.html | 112 +++ .../reference/operators/comma_operator/index.html | 84 ++ .../operators/comparison_operators/index.html | 277 ++++++ .../operators/conditional_operator/index.html | 126 +++ .../reference/operators/delete/index.html | 298 +++++++ .../operators/destructuring_assignment/index.html | 431 +++++++++ .../reference/operators/division/index.html | 76 ++ .../operators/division_assignment/index.html | 58 ++ .../reference/operators/exponentiation/index.html | 107 +++ .../operators/exponentiation_assignment/index.html | 59 ++ .../operators/expression_closures/index.html | 76 ++ .../reference/operators/function/index.html | 182 ++++ .../reference/operators/function_star_/index.html | 89 ++ .../operators/generator_comprehensions/index.html | 193 ++++ .../reference/operators/greater_than/index.html | 95 ++ .../operators/greater_than_or_equal/index.html | 95 ++ .../reference/operators/grouping/index.html | 93 ++ .../javascript/reference/operators/in/index.html | 145 +++ .../reference/operators/increment/index.html | 84 ++ .../web/javascript/reference/operators/index.html | 297 +++++++ .../reference/operators/inequality/index.html | 104 +++ .../reference/operators/instanceof/index.html | 186 ++++ .../reference/operators/left_shift/index.html | 72 ++ .../operators/left_shift_assignment/index.html | 59 ++ .../reference/operators/less_than/index.html | 110 +++ .../operators/less_than_or_equal/index.html | 97 ++ .../operators/logical_and_assignment/index.html | 83 ++ .../reference/operators/logical_not/index.html | 104 +++ .../logical_nullish_assignment/index.html | 82 ++ .../operators/logical_operators/index.html | 237 +++++ .../reference/operators/logical_or/index.html | 146 +++ .../operators/logical_or_assignment/index.html | 87 ++ .../reference/operators/multiplication/index.html | 69 ++ .../operators/multiplication_assignment/index.html | 55 ++ .../reference/operators/new.target/index.html | 99 +++ .../javascript/reference/operators/new/index.html | 201 +++++ .../nullish_coalescing_operator/index.html | 158 ++++ .../operators/object_initializer/index.html | 314 +++++++ .../operators/operator_precedence/index.html | 351 ++++++++ .../operators/property_accessors/index.html | 153 ++++ .../operators/remainder_assignment/index.html | 56 ++ .../reference/operators/right_shift/index.html | 75 ++ .../operators/right_shift_assignment/index.html | 59 ++ .../reference/operators/spread_syntax/index.html | 245 +++++ .../reference/operators/strict_equality/index.html | 101 +++ .../operators/strict_inequality/index.html | 95 ++ .../reference/operators/subtraction/index.html | 67 ++ .../operators/subtraction_assignment/index.html | 59 ++ .../reference/operators/super/index.html | 184 ++++ .../javascript/reference/operators/this/index.html | 498 +++++++++++ .../reference/operators/typeof/index.html | 286 ++++++ .../reference/operators/unary_negation/index.html | 73 ++ .../reference/operators/unary_plus/index.html | 75 ++ .../operators/unsigned_right_shift/index.html | 71 ++ .../unsigned_right_shift_assignment/index.html | 55 ++ .../javascript/reference/operators/void/index.html | 114 +++ .../reference/operators/yield/index.html | 104 +++ .../reference/operators/yield_star_/index.html | 162 ++++ .../operators/\345\217\226\344\275\231/index.html" | 81 ++ .../index.html" | 202 +++++ .../index.html" | 106 +++ .../operators/\347\233\270\345\212\240/index.html" | 79 ++ .../operators/\347\233\270\347\255\211/index.html" | 125 +++ .../index.html" | 75 ++ .../operators/\350\207\252\345\207\217/index.html" | 85 ++ .../index.html" | 137 +++ .../javascript/reference/reserved_words/index.html | 81 ++ .../reference/statements/async_function/index.html | 327 +++++++ .../reference/statements/block/index.html | 163 ++++ .../reference/statements/break/index.html | 175 ++++ .../reference/statements/class/index.html | 119 +++ .../reference/statements/const/index.html | 152 ++++ .../reference/statements/continue/index.html | 156 ++++ .../reference/statements/debugger/index.html | 79 ++ .../reference/statements/default/index.html | 119 +++ .../reference/statements/do...while/index.html | 99 +++ .../reference/statements/empty/index.html | 103 +++ .../reference/statements/export/index.html | 268 ++++++ .../reference/statements/for-await...of/index.html | 161 ++++ .../reference/statements/for...in/index.html | 157 ++++ .../reference/statements/for...of/index.html | 313 +++++++ .../javascript/reference/statements/for/index.html | 169 ++++ .../reference/statements/for_each...in/index.html | 69 ++ .../reference/statements/function/index.html | 179 ++++ .../reference/statements/function_star_/index.html | 242 +++++ .../reference/statements/if...else/index.html | 176 ++++ .../reference/statements/import.meta/index.html | 104 +++ .../reference/statements/import/index.html | 232 +++++ .../web/javascript/reference/statements/index.html | 150 ++++ .../reference/statements/label/index.html | 203 +++++ .../javascript/reference/statements/let/index.html | 279 ++++++ .../reference/statements/return/index.html | 149 ++++ .../reference/statements/switch/index.html | 308 +++++++ .../reference/statements/throw/index.html | 195 ++++ .../reference/statements/try...catch/index.html | 302 +++++++ .../javascript/reference/statements/var/index.html | 216 +++++ .../reference/statements/while/index.html | 101 +++ .../reference/statements/with/index.html | 131 +++ .../javascript/reference/strict_mode/index.html | 375 ++++++++ .../transitioning_to_strict_mode/index.html | 128 +++ .../reference/template_strings/index.html | 261 ++++++ .../reference/trailing_commas/index.html | 182 ++++ files/zh-cn/web/javascript/shells/index.html | 47 + .../index.html | 142 +++ files/zh-cn/web/javascript/typed_arrays/index.html | 174 ++++ 887 files changed, 123570 insertions(+) create mode 100644 files/zh-cn/web/javascript/a_re-introduction_to_javascript/index.html create mode 100644 files/zh-cn/web/javascript/about_javascript/index.html create mode 100644 files/zh-cn/web/javascript/closures/index.html create mode 100644 files/zh-cn/web/javascript/data_structures/index.html create mode 100644 files/zh-cn/web/javascript/ecmascript_7_support_in_mozilla/index.html create mode 100644 files/zh-cn/web/javascript/enumerability_and_ownership_of_properties/index.html create mode 100644 files/zh-cn/web/javascript/equality_comparisons_and_sameness/index.html create mode 100644 files/zh-cn/web/javascript/eventloop/index.html create mode 100644 files/zh-cn/web/javascript/getting_started/index.html create mode 100644 files/zh-cn/web/javascript/guide/about/index.html create mode 100644 files/zh-cn/web/javascript/guide/control_flow_and_error_handling/index.html create mode 100644 files/zh-cn/web/javascript/guide/details_of_the_object_model/index.html create mode 100644 files/zh-cn/web/javascript/guide/expressions_and_operators/index.html create mode 100644 files/zh-cn/web/javascript/guide/functions/index.html create mode 100644 files/zh-cn/web/javascript/guide/grammar_and_types/index.html create mode 100644 files/zh-cn/web/javascript/guide/index.html create mode 100644 files/zh-cn/web/javascript/guide/indexed_collections/index.html create mode 100644 files/zh-cn/web/javascript/guide/introduction/index.html create mode 100644 files/zh-cn/web/javascript/guide/iterators_and_generators/index.html create mode 100644 files/zh-cn/web/javascript/guide/javascript_overview/index.html create mode 100644 files/zh-cn/web/javascript/guide/keyed_collections/index.html create mode 100644 files/zh-cn/web/javascript/guide/loops_and_iteration/index.html create mode 100644 files/zh-cn/web/javascript/guide/meta_programming/index.html create mode 100644 files/zh-cn/web/javascript/guide/modules/index.html create mode 100644 files/zh-cn/web/javascript/guide/numbers_and_dates/index.html create mode 100644 files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html create mode 100644 files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html create mode 100644 files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html create mode 100644 files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html create mode 100644 files/zh-cn/web/javascript/guide/regular_expressions/index.html create mode 100644 files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html create mode 100644 "files/zh-cn/web/javascript/guide/regular_expressions/\351\207\217\350\257\215/index.html" create mode 100644 files/zh-cn/web/javascript/guide/text_formatting/index.html create mode 100644 files/zh-cn/web/javascript/guide/using_promises/index.html create mode 100644 files/zh-cn/web/javascript/guide/working_with_objects/index.html create mode 100644 files/zh-cn/web/javascript/index.html create mode 100644 files/zh-cn/web/javascript/inheritance_and_the_prototype_chain/index.html create mode 100644 files/zh-cn/web/javascript/introduction_to_object-oriented_javascript/index.html create mode 100644 files/zh-cn/web/javascript/introduction_to_using_xpath_in_javascript/index.html create mode 100644 "files/zh-cn/web/javascript/javascript(\350\265\267\346\255\245)/index.html" create mode 100644 files/zh-cn/web/javascript/javascript_technologies_overview/index.html create mode 100644 files/zh-cn/web/javascript/language_resources/index.html create mode 100644 files/zh-cn/web/javascript/memory_management/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.1/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.2/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.3/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.4/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.5/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.6/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.7/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.8.1/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.8.5/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.8/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/ecmascript_5_support_in_mozilla/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/ecmascript_6_support_in_mozilla/index.html create mode 100644 files/zh-cn/web/javascript/new_in_javascript/index.html create mode 100644 files/zh-cn/web/javascript/reference/about/index.html create mode 100644 files/zh-cn/web/javascript/reference/classes/class_elements/index.html create mode 100644 files/zh-cn/web/javascript/reference/classes/constructor/index.html create mode 100644 files/zh-cn/web/javascript/reference/classes/extends/index.html create mode 100644 files/zh-cn/web/javascript/reference/classes/index.html create mode 100644 files/zh-cn/web/javascript/reference/classes/private_class_fields/index.html create mode 100644 files/zh-cn/web/javascript/reference/classes/static/index.html create mode 100644 files/zh-cn/web/javascript/reference/deprecated_and_obsolete_features/index.html create mode 100644 files/zh-cn/web/javascript/reference/deprecated_and_obsolete_features/the_legacy_iterator_protocol/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/already_has_pragma/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/array_sort_argument/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/bad_octal/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/bad_radix/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/bad_regexp_flag/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/bad_return_or_yield/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/called_on_incompatible_type/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/cant_access_lexical_declaration_before_init/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/cant_access_property/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/cant_define_property_object_not_extensible/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/cant_delete/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/cant_redefine_property/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/cyclic_object_value/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/dead_object/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/delete_in_strict_mode/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/deprecated_caller_or_arguments_usage/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/deprecated_expression_closures/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/deprecated_octal/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/deprecated_source_map_pragma/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/deprecated_string_generics/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/deprecated_tolocaleformat/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/equal_as_assign/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/for-each-in_loops_are_deprecated/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/getter_only/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/identifier_after_number/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/illegal_character/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/in_operator_no_object/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/invalid_array_length/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/invalid_assignment_left-hand_side/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/invalid_const_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/invalid_date/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/invalid_for-in_initializer/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/invalid_for-of_initializer/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/invalid_right_hand_side_instanceof_operand/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/is_not_iterable/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/json_bad_parse/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/malformed_formal_parameter/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/malformed_uri/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_bracket_after_list/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_colon_after_property_id/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_curly_after_function_body/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_curly_after_property_list/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_formal_parameter/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_initializer_in_const/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_name_after_dot_operator/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_parenthesis_after_argument_list/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_parenthesis_after_condition/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/missing_semicolon_before_statement/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/more_arguments_needed/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/negative_repetition_count/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/no_non-null_object/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/no_properties/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/no_variable_name/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/non_configurable_array_element/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/not_a_codepoint/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/not_a_constructor/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/not_a_function/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/not_defined/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/precision_range/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/property_access_denied/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/read-only/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/redeclared_parameter/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/reduce_of_empty_array_with_no_initial_value/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/reserved_identifier/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/resulting_string_too_large/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/stmt_after_return/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/strict_non_simple_params/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/too_much_recursion/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/typed_array_invalid_arguments/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/undeclared_var/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/undefined_prop/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/unexpected_token/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/unexpected_type/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/unnamed_function_statement/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/unterminated_string_literal/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/var_hides_argument/index.html create mode 100644 "files/zh-cn/web/javascript/reference/errors/\344\270\215\350\203\275\346\267\273\345\212\240\345\261\236\346\200\247/index.html" create mode 100644 files/zh-cn/web/javascript/reference/functions/arguments/@@iterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/arguments/callee/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/arguments/caller/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/arguments/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/arguments/length/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/arrow_functions/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/default_parameters/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/get/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/method_definitions/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/rest_parameters/index.html create mode 100644 files/zh-cn/web/javascript/reference/functions/set/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/aggregateerror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/@@iterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/@@species/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/@@unscopables/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/concat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/copywithin/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/entries/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/every/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/fill/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/filter/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/find/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/findindex/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/flat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/flatmap/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/foreach/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/from/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/includes/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/indexof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/isarray/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/join/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/keys/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/lastindexof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/length/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/map/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/observe/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/of/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/pop/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/push/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/reduce/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/reduceright/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/reverse/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/shift/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/slice/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/some/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/sort/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/splice/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/tolocalestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/unobserve/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/unshift/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/values/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/arraybuffer/@@species/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/arraybuffer/bytelength/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/arraybuffer/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/arraybuffer/isview/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/arraybuffer/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/arraybuffer/slice/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/arraybuffer/transfer/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/asyncfunction/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/asyncfunction/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/asynciterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/add/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/and/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/compareexchange/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/exchange/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/islockfree/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/load/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/notify/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/or/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/store/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/sub/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/wait/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/atomics/xor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/bigint/asintn/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/bigint/asuintn/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/bigint/bigint/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/bigint/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/bigint/tolocalestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/bigint/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/bigint/valueof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/bigint64array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/biguint64array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/boolean/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/boolean/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/boolean/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/boolean/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/boolean/valueof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/buffer/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/bytelength/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/byteoffset/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getbigint64/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getbiguint64/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getfloat32/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getfloat64/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getint16/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getint32/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getint8/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getuint16/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getuint32/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/getuint8/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setbigint64/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setbiguint64/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setfloat32/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setfloat64/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setint16/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setint32/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setint8/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setuint16/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setuint32/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/setuint8/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/@@toprimitive/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/date/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getdate/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getday/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getfullyear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/gethours/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getmilliseconds/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getminutes/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getmonth/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getseconds/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/gettime/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/gettimezoneoffset/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getutcdate/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getutcday/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getutcfullyear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getutchours/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getutcmilliseconds/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getutcminutes/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getutcmonth/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getutcseconds/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/getyear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/now/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/parse/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setdate/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setfullyear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/sethours/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setmilliseconds/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setminutes/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setmonth/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setseconds/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/settime/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setutcdate/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setutcfullyear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setutchours/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setutcmilliseconds/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setutcminutes/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setutcmonth/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setutcseconds/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/setyear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/todatestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/togmtstring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/toisostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/tojson/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/tolocaledatestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/tolocaleformat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/tolocalestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/tolocaletimestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/totimestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/toutcstring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/utc/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/valueof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/decodeuri/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/decodeuricomponent/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/encodeuri/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/encodeuricomponent/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/columnnumber/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/filename/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/linenumber/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/message/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/name/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/stack/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/escape/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/eval/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/evalerror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/evalerror/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/finalizationregistry/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/float32array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/float64array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/apply/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/arguments/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/arity/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/bind/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/call/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/caller/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/displayname/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/isgenerator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/length/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/name/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/generator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/generator/next/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/generator/return/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/generator/throw/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/generatorfunction/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/generatorfunction/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/globalthis/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/infinity/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/int16array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/int32array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/int8array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/internalerror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/collator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/displaynames/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/getcanonicallocales/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/listformat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/locale/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/numberformat/format/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/numberformat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/pluralrules/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/relativetimeformat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/isfinite/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/isnan/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/iterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/json/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/json/parse/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/json/stringify/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/@@iterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/@@species/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/@@tostringtag/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/clear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/delete/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/entries/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/foreach/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/get/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/has/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/keys/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/map/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/set/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/size/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/values/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/abs/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/acos/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/asin/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/asinh/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/atan/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/atan2/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/atanh/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/cbrt/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/ceil/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/clz32/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/cos/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/cosh/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/e/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/exp/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/expm1/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/floor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/fround/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/hypot/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/ln10/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/ln2/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/log/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/log10/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/log10e/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/log1p/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/log2/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/log2e/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/max/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/min/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/pi/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/pow/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/random/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/round/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/sign/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/sin/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/sinh/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/sqrt/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/sqrt1_2/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/sqrt2/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/tan/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/tanh/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/trunc/index.html create mode 100644 "files/zh-cn/web/javascript/reference/global_objects/math/\345\217\215\345\217\214\346\233\262\344\275\231\345\274\246\345\200\274/index.html" create mode 100644 files/zh-cn/web/javascript/reference/global_objects/nan/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/null/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/epsilon/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/isfinite/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/isinteger/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/isnan/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/issafeinteger/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/max_safe_integer/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/max_value/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/min_safe_integer/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/min_value/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/nan/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/negative_infinity/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/number/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/parsefloat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/parseint/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/positive_infinity/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/toexponential/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/tofixed/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/tointeger/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/tolocalestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/toprecision/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/valueof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/__definegetter__/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/__definesetter__/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/__lookupgetter__/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/__lookupsetter__/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/assign/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/constructor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/count/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/create/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/defineproperties/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/defineproperty/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/entries/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/eval/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/freeze/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/fromentries/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/getnotifier/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/getownpropertydescriptor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/getownpropertydescriptors/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/getownpropertynames/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/getownpropertysymbols/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/getprototypeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/hasownproperty/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/is/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/isextensible/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/isfrozen/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/isprototypeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/issealed/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/keys/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/nosuchmethod/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/object/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/observe/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/parent/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/preventextensions/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/propertyisenumerable/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/proto/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/seal/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/setprototypeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/tolocalestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/unobserve/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/unwatch/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/valueof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/values/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/watch/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/parallelarray/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/parsefloat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/parseint/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/all/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/allsettled/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/any/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/catch/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/finally/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/promise/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/race/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/reject/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/resolve/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/then/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/apply/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/construct/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/defineproperty/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/get/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getownpropertydescriptor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getprototypeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/has/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/isextensible/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/ownkeys/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/preventextensions/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/set/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/setprototypeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/revocable/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/rangeerror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/rangeerror/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/referenceerror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/referenceerror/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/apply/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/construct/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/defineproperty/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/deleteproperty/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/get/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/getownpropertydescriptor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/getprototypeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/has/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/isextensible/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/ownkeys/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/preventextensions/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/set/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/setprototypeof/index.html create mode 100644 "files/zh-cn/web/javascript/reference/global_objects/reflect/\346\257\224\350\276\203_reflect_\345\222\214_object_\346\226\271\346\263\225/index.html" create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/@@match/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/@@matchall/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/@@replace/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/@@search/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/@@species/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/@@split/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/compile/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/dotall/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/exec/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/flags/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/global/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/ignorecase/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/input/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/lastindex/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/lastmatch/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/lastparen/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/leftcontext/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/multiline/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/n/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/regexp/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/rightcontext/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/source/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/sticky/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/test/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/unicode/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/@@iterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/@@species/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/add/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/clear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/delete/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/entries/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/foreach/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/has/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/set/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/size/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/set/values/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/bytelength/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/slice/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/@@iterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/anchor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/big/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/blink/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/bold/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/charat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/charcodeat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/codepointat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/concat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/endswith/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/fixed/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/fontcolor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/fontsize/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/fromcharcode/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/fromcodepoint/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/includes/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/indexof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/italics/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/lastindexof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/length/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/link/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/localecompare/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/match/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/matchall/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/normalize/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/padend/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/padstart/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/quote/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/raw/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/repeat/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/replace/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/replaceall/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/search/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/slice/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/small/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/split/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/startswith/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/strike/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/sub/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/substr/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/substring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/sup/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/tolocalelowercase/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/tolocaleuppercase/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/tolowercase/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/touppercase/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/trim/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/trimleft/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/trimright/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/valueof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/@@toprimitive/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/asynciterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/description/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/for/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/hasinstance/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/isconcatspreadable/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/iterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/keyfor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/match/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/matchall/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/replace/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/search/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/species/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/split/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/toprimitive/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/tosource/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/tostringtag/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/unscopables/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/valueof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/syntaxerror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/syntaxerror/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/@@iterator/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/@@species/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/buffer/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/bytelength/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/byteoffset/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/bytes_per_element/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/copywithin/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/entries/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/every/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/fill/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/filter/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/find/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/findindex/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/foreach/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/from/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/includes/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/indexof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/join/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/keys/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/lastindexof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/length/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/map/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/name/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/of/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/reduce/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/reduceright/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/reverse/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/set/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/slice/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/some/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/sort/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/subarray/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/tolocalestring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/tostring/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/values/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typeerror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/typeerror/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/uint16array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/uint32array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/uint8array/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/uint8clampedarray/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/undefined/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/unescape/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/uneval/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/urierror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/urierror/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakmap/clear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakmap/delete/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakmap/get/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakmap/has/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakmap/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakmap/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakmap/set/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakref/deref/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakref/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakset/add/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakset/clear/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakset/delete/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakset/has/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakset/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakset/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/compile/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/compileerror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/compilestreaming/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/global/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/instance/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/instantiate/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/instantiatestreaming/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/memory/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/module/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/runtimeerror/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/table/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/webassembly/validate/index.html create mode 100644 files/zh-cn/web/javascript/reference/index.html create mode 100644 files/zh-cn/web/javascript/reference/iteration_protocols/index.html create mode 100644 files/zh-cn/web/javascript/reference/lexical_grammar/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/addition_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html create mode 100644 "files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" create mode 100644 files/zh-cn/web/javascript/reference/operators/await/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_and_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_not/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_or/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_or_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_xor/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_xor_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/class/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/comma_operator/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/conditional_operator/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/delete/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/destructuring_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/division/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/division_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/exponentiation/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/exponentiation_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/expression_closures/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/function/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/function_star_/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/greater_than/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/greater_than_or_equal/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/grouping/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/in/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/increment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/inequality/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/instanceof/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/left_shift/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/left_shift_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/less_than/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/less_than_or_equal/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_and_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_not/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_nullish_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_or/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_or_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/multiplication/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/multiplication_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/new.target/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/new/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/nullish_coalescing_operator/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/object_initializer/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/operator_precedence/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/property_accessors/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/remainder_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/right_shift/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/right_shift_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/spread_syntax/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/strict_equality/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/strict_inequality/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/subtraction/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/subtraction_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/super/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/this/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/typeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/unary_negation/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/unary_plus/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/unsigned_right_shift/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/unsigned_right_shift_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/void/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/yield/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/yield_star_/index.html create mode 100644 "files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" create mode 100644 files/zh-cn/web/javascript/reference/reserved_words/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/async_function/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/block/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/break/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/class/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/const/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/continue/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/debugger/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/default/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/do...while/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/empty/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/export/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/for-await...of/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/for...in/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/for...of/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/for/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/for_each...in/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/function/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/function_star_/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/if...else/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/import.meta/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/import/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/label/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/let/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/return/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/switch/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/throw/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/try...catch/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/var/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/while/index.html create mode 100644 files/zh-cn/web/javascript/reference/statements/with/index.html create mode 100644 files/zh-cn/web/javascript/reference/strict_mode/index.html create mode 100644 files/zh-cn/web/javascript/reference/strict_mode/transitioning_to_strict_mode/index.html create mode 100644 files/zh-cn/web/javascript/reference/template_strings/index.html create mode 100644 files/zh-cn/web/javascript/reference/trailing_commas/index.html create mode 100644 files/zh-cn/web/javascript/shells/index.html create mode 100644 files/zh-cn/web/javascript/the_performance_hazards_of__[[prototype]]_mutation/index.html create mode 100644 files/zh-cn/web/javascript/typed_arrays/index.html (limited to 'files/zh-cn/web/javascript') diff --git a/files/zh-cn/web/javascript/a_re-introduction_to_javascript/index.html b/files/zh-cn/web/javascript/a_re-introduction_to_javascript/index.html new file mode 100644 index 0000000000..0f423505da --- /dev/null +++ b/files/zh-cn/web/javascript/a_re-introduction_to_javascript/index.html @@ -0,0 +1,959 @@ +--- +title: 重新介绍 JavaScript(JS 教程) +slug: Web/JavaScript/A_re-introduction_to_JavaScript +tags: + - JavaScript + - 指南 + - 教程 + - 进阶 + - 高级 +translation_of: Web/JavaScript/A_re-introduction_to_JavaScript +--- +
{{jsSidebar}}
+ +

为什么会有这一篇“重新介绍”呢?因为 {{Glossary("JavaScript")}} 堪称世界上被人误解最深的编程语言。虽然常被嘲为“玩具语言”,但在它看似简洁的外衣下,还隐藏着强大的语言特性。 JavaScript 目前广泛应用于众多知名应用中,对于网页和移动开发者来说,深入理解 JavaScript 就尤为必要。

+ +

我们有必要先从这门语言的历史谈起。在1995 年 Netscape 一位名为 Brendan Eich 的工程师创造了 JavaScript,随后在 1996 年初,JavaScript 首先被应用于 Netscape 2 浏览器上。最初的 JavaScript 名为 LiveScript,但是因为一个糟糕的营销策略而被重新命名,该策略企图利用Sun Microsystem的Java语言的流行性,将它的名字从最初的 LiveScript 更改为 JavaScript——尽管两者之间并没有什么共同点。这便是之后混淆产生的根源。

+ +

几个月后,Microsoft 随 IE 3 发布推出了一个与之基本兼容的语言 JScript。又过了几个月,Netscape 将 JavaScript 提交至 Ecma International(一个欧洲标准化组织), {{Glossary("ECMAScript")}} 标准第一版便在 1997 年诞生了,随后在 1999 年以 ECMAScript 第三版的形式进行了更新,从那之后这个标准没有发生过大的改动。由于委员会在语言特性的讨论上发生分歧,ECMAScript 第四版尚未推出便被废除,但随后于 2009 年 12 月发布的 ECMAScript 第五版引入了第四版草案加入的许多特性。第六版标准已经于 2015 年 6 月发布。

+ +
+

注意: 由于这种用法更常见,从这里开始,我们将使用 JavaScript 来指代 ECMAScript 。

+
+ +

与大多数编程语言不同,JavaScript 没有输入或输出的概念。它是一个在宿主环境(host environment)下运行的脚本语言,任何与外界沟通的机制都是由宿主环境提供的。浏览器是最常见的宿主环境,但在非常多的其他程序中也包含 JavaScript 解释器,如 Adobe Acrobat、Adobe Photoshop、SVG 图像、Yahoo! 的 Widget 引擎,Node.js 之类的服务器端环境,NoSQL 数据库(如开源的 Apache CouchDB)、嵌入式计算机,以及包括 GNOME (注:GNU/Linux 上最流行的 GUI 之一)在内的桌面环境等等。

+ +

概览

+ +

JavaScript 是一种多范式的动态语言,它包含类型、运算符、标准内置( built-in)对象和方法。它的语法来源于 Java 和 C,所以这两种语言的许多语法特性同样适用于 JavaScript。JavaScript 通过原型链而不是类来支持面向对象编程(有关 ES6 类的内容参考这里{{jsxref("Classes")}},有关对象原型参考见此继承与原型链)。JavaScript同样支持函数式编程——因为它们也是对象,函数也可以被保存在变量中,并且像其他对象一样被传递。

+ +

先从任何编程语言都不可缺少的组成部分——“类型”开始。JavaScript 程序可以修改值(value),这些值都有各自的类型。JavaScript 中的类型包括:

+ + + +

…哦,还有看上去有些…奇怪的 {{jsxref("undefined")}}(未定义)类型和 {{jsxref("null")}}(空)类型。此外还有{{jsxref("Array")}}(数组)类型,以及分别用于表示日期和正则表达式的 {{jsxref("Date")}}(日期)和 {{jsxref("RegExp")}}(正则表达式),这三种类型都是特殊的对象。严格意义上说,Function(函数)也是一种特殊的对象。所以准确来说,JavaScript 中的类型应该包括这些:

+ + + +

JavaScript 还有一种内置的 {{jsxref("Error")}}(错误)类型。但是,如果我们继续使用上面的分类,事情便容易得多;所以,现在,我们先讨论上面这些类型。

+ +

数字

+ +

根据语言规范,JavaScript 采用“遵循 IEEE 754 标准的双精度 64 位格式”("double-precision 64-bit format IEEE 754 values")表示数字。——在JavaScript(除了{{jsxref("BigInt")}})当中,并不存在整数/整型(Integer)。因此在处理如下的场景时候,您一定要小心:

+ +
console.log(3 / 2);             // 1.5,not 1
+console.log(Math.floor(3 / 2)); // 1
+
+ +

一个看上去是整数的东西,其实都是浮点数。

+ +

当然,您也需要小心这种情况:

+ +
0.1 + 0.2 = 0.30000000000000004
+
+ +

在具体实现时,整数值通常被视为32位整型变量,在个别实现(如某些浏览器)中也以32位整型变量的形式进行存储,直到它被用于执行某些32位整型不支持的操作,这是为了便于进行位操作。

+ +

JavaScript 支持标准的算术运算符,包括加法、减法、取模(或取余)等等。还有一个之前没有提及的内置对象 {{jsxref("Math")}}(数学对象),用以处理更多的高级数学函数和常数:

+ +
Math.sin(3.5);
+var circumference = 2 * Math.PI * r;
+
+ +

你可以使用内置函数 {{jsxref("Global_Objects/parseInt", "parseInt()")}} 将字符串转换为整型。该函数的第二个可选参数表示字符串所表示数字的基(进制):

+ +
parseInt("123", 10); // 123
+parseInt("010", 10); // 10
+
+ +

一些老版本的浏览器会将首字符为“0”的字符串当做八进制数字,2013 年以前的 JavaScript 实现会返回一个意外的结果:

+ +
parseInt("010");  //  8
+parseInt("0x10"); // 16
+ +

这是因为字符串以数字 0 开头,{{jsxref("Global_Objects/parseInt", "parseInt()")}}函数会把这样的字符串视作八进制数字;同理,0x开头的字符串则视为十六进制数字。

+ +

如果想把一个二进制数字字符串转换成整数值,只要把第二个参数设置为 2 就可以了:

+ +
parseInt("11", 2); // 3
+
+ +

JavaScript 还有一个类似的内置函数 {{jsxref("Global_Objects/parseFloat", "parseFloat()")}},用以解析浮点数字符串,与{{jsxref("Global_Objects/parseInt", "parseInt()")}}不同的地方是,parseFloat() 只应用于解析十进制数字。

+ +

一元运算符 + 也可以把数字字符串转换成数值:

+ +
+ "42";   // 42
++ "010";  // 10
++ "0x10"; // 16
+ +

如果给定的字符串不存在数值形式,函数会返回一个特殊的值 {{jsxref("NaN")}}(Not a Number 的缩写):

+ +
parseInt("hello", 10); // NaN
+
+ +

要小心NaN:如果把 NaN 作为参数进行任何数学运算,结果也会是 NaN

+ +
NaN + 5; //NaN
+
+ +

可以使用内置函数 isNaN() 来判断一个变量是否为 NaN

+ +
isNaN(NaN); // true
+
+ +

JavaScript 还有两个特殊值:Infinity(正无穷)和 -Infinity(负无穷):

+ +
1 / 0; //  Infinity
+-1 / 0; // -Infinity
+
+ +

可以使用内置函数 isFinite() 来判断一个变量是否是一个有穷数, 如果类型为Infinity, -InfinityNaN则返回false

+ +
isFinite(1/0); // false
+isFinite(Infinity); // false
+isFinite(-Infinity); // false
+isFinite(NaN); // false
+
+isFinite(0); // true
+isFinite(2e64); // true
+
+isFinite("0"); // true
+// 如果是纯数值类型的检测,则返回 false:
+Number.isFinite("0"); // false
+ +
备注: {{jsxref("Global_Objects/parseInt", "parseInt()")}} 和 {{jsxref("Global_Objects/parseFloat", "parseFloat()")}} 函数会尝试逐个解析字符串中的字符,直到遇上一个无法被解析成数字的字符,然后返回该字符前所有数字字符组成的数字。但是运算符 "+"对字符串的转换方式与之不同, 只要字符串含有无法被解析成数字的字符,该字符串就将被转换成 NaN。可分别使用这两种方法解析“10.2abc”这一字符串,并比较得到的结果,来理解这两种方法的区别。
+ +

字符串

+ +

JavaScript 中的字符串是一串Unicode 字符序列。这对于那些需要和多语种网页打交道的开发者来说是个好消息。更准确地说,它们是一串UTF-16编码单元的序列,每一个编码单元由一个 16 位二进制数表示。每一个Unicode字符由一个或两个编码单元来表示。

+ +

如果想表示一个单独的字符,只需使用长度为 1 的字符串。

+ +

通过访问字符串的 length(编码单元的个数)属性,可以得到它的长度。

+ +
"hello".length; // 5
+
+ +

这是我们第一次碰到 JavaScript 对象。我们有没有提过你可以像  {{jsxref("Object", "object", "", 1)}}  一样使用字符串?是的,字符串也有 {{jsxref("String", "methods", "#Methods", 1)}}(方法)能让你操作字符串和获取字符串的信息。

+ +
"hello".charAt(0); // "h"
+"hello, world".replace("world", "mars"); // "hello, mars"
+"hello".toUpperCase(); // "HELLO"
+
+ +

其他类型

+ +

与其他类型不同,JavaScript 中的 {{jsxref("null")}} 表示一个空值(non-value),必须使用 null 关键字才能访问,{{jsxref("undefined")}} 是一个“undefined(未定义)”类型的对象,表示一个未初始化的值,也就是还没有被分配的值。我们之后再具体讨论变量,但有一点可以先简单说明一下,JavaScript 允许声明变量但不对其赋值,一个未被赋值的变量就是 undefined 类型。还有一点需要说明的是,undefined 实际上是一个不允许修改的常量。

+ +

JavaScript 包含布尔类型,这个类型的变量有两个可能的值,分别是 truefalse(两者都是关键字)。根据具体需要,JavaScript 按照如下规则将变量转换成布尔类型:

+ +
    +
  1. false0、空字符串("")、NaNnullundefined 被转换为 false
  2. +
  3. 所有其他值被转换为 true
  4. +
+ +

也可以使用 Boolean() 函数进行显式转换:

+ +
Boolean(''); // false
+Boolean(234); // true
+
+ +

不过一般没必要这么做,因为 JavaScript 会在需要一个布尔变量时隐式完成这个转换操作(比如在 if 条件语句中)。所以,有时我们可以把转换成布尔值后的变量分别称为 真值(true values)——即值为 true  和 假值(false values)——即值为 false;也可以分别称为“真的”(truthy)和“假的”(falsy)。

+ +

JavaScript 支持包括 &&(逻辑与)、|| (逻辑或)和!(逻辑非)在内的一些逻辑运算符。下面会有所提到。

+ +

变量

+ +

在 JavaScript 中声明一个新变量的方法是使用关键字 letconstvar

+ +

let 语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。

+ +
let a;
+let name = 'Simon';
+ +

下面是使用  let 声明变量作用域的例子:

+ +
// myLetVariable 在这里 *不能* 被引用
+
+for (let myLetVariable = 0; myLetVariable < 5; myLetVariable++) {
+  // myLetVariable 只能在这里引用
+}
+
+// myLetVariable 在这里 *不能* 被引用
+ +

const 允许声明一个不可变的常量。这个常量在定义域内总是可见的。

+ +
const Pi = 3.14; // 设置 Pi 的值
+Pi = 1; // 将会抛出一个错误因为你改变了一个常量的值。
+ +

var 是最常见的声明变量的关键字。它没有其他两个关键字的种种限制。这是因为它是传统上在 JavaScript 声明变量的唯一方法。使用 var 声明的变量在它所声明的整个函数都是可见的。

+ +
var a;
+var name = "simon";
+
+ +

一个使用  var 声明变量的语句块的例子:

+ +
// myVarVariable在这里 *能* 被引用
+
+for (var myVarVariable = 0; myVarVariable < 5; myVarVariable++) {
+  // myVarVariable 整个函数中都能被引用
+}
+
+// myVarVariable 在这里 *能* 被引用
+ +

如果声明了一个变量却没有对其赋值,那么这个变量的类型就是 undefined

+ +

JavaScript 与其他语言的(如 Java)的重要区别是在 JavaScript 中语句块(blocks)是没有作用域的,只有函数有作用域。因此如果在一个复合语句中(如 if 控制结构中)使用 var 声明一个变量,那么它的作用域是整个函数(复合语句在函数中)。 但是从 ECMAScript Edition 6 开始将有所不同的, let 和 const 关键字允许你创建块作用域的变量。

+ +

运算符

+ +

JavaScript的算术操作符包括 +-*/% ——求余(与模运算相同)。赋值使用 = 运算符,此外还有一些复合运算符,如 +=-=,它们等价于 x = x operator y

+ +
x += 5; // 等价于 x = x + 5;
+
+ +

可以使用 ++-- 分别实现变量的自增和自减。两者都可以作为前缀或后缀操作符使用。

+ +

+ 操作符还可以用来连接字符串:

+ +
"hello" + " world"; // hello world
+
+ +

如果你用一个字符串加上一个数字(或其他值),那么操作数都会被首先转换为字符串。如下所示:

+ +
"3" + 4 + 5; // 345
+3 + 4 + "5"; // 75
+
+ +

这里不难看出一个实用的技巧——通过与空字符串相加,可以将某个变量快速转换成字符串类型。

+ +

JavaScript 中的比较操作使用 <><=>=,这些运算符对于数字和字符串都通用。相等的比较稍微复杂一些。由两个“=(等号)”组成的相等运算符有类型自适应的功能,具体例子如下:

+ +
123 == "123" // true
+1 == true; // true
+
+ +

如果在比较前不需要自动类型转换,应该使用由三个“=(等号)”组成的相等运算符:

+ +
1 === true; //false
+123 === "123"; // false
+
+ +

JavaScript 还支持 !=!== 两种不等运算符,具体区别与两种相等运算符的区别类似。

+ +

JavaScript 还提供了 位操作符

+ +

控制结构

+ +

JavaScript 的控制结构与其他类 C 语言类似。可以使用 ifelse 来定义条件语句,还可以连起来使用:

+ +
var name = "kittens";
+if (name == "puppies") {
+  name += "!";
+} else if (name == "kittens") {
+  name += "!!";
+} else {
+  name = "!" + name;
+}
+name == "kittens!!"; // true
+
+ +

JavaScript 支持 while 循环和 do-while 循环。前者适合常见的基本循环操作,如果需要循环体至少被执行一次则可以使用 do-while

+ +
while (true) {
+  // 一个无限循环!
+}
+
+var input;
+do {
+  input = get_input();
+} while (inputIsNotValid(input))
+
+ +

JavaScript 的 for 循环与 C 和 Java 中的相同:使用时可以在一行代码中提供控制信息。

+ +
for (var i = 0; i < 5; i++) {
+  // 将会执行五次
+}
+
+ +

JavaScript 也还包括其他两种重要的 for 循环: for...of

+ +
for (let value of array) {
+  // do something with value
+}
+ +

for...in

+ +
for (let property in object) {
+  // do something with object property
+}
+ +

&&|| 运算符使用短路逻辑(short-circuit logic),是否会执行第二个语句(操作数)取决于第一个操作数的结果。在需要访问某个对象的属性时,使用这个特性可以事先检测该对象是否为空:

+ +
var name = o && o.getName();
+
+ +

或用于缓存值(当错误值无效时):

+ +
var name = cachedName || (cachedName = getName());
+
+ +

类似地,JavaScript 也有一个用于条件表达式的三元操作符:

+ +
var allowed = (age > 18) ? "yes" : "no";
+
+ +

在需要多重分支时可以使用  基于一个数字或字符串的switch 语句:

+ +
switch(action) {
+    case 'draw':
+        drawIt();
+        break;
+    case 'eat':
+        eatIt();
+        break;
+    default:
+        doNothing();
+}
+
+ +

如果你不使用 break 语句,JavaScript 解释器将会执行之后 case 中的代码。除非是为了调试,一般你并不需要这个特性,所以大多数时候不要忘了加上 break。

+ +
switch(a) {
+    case 1: // 继续向下
+    case 2:
+        eatIt();
+        break;
+    default:
+        doNothing();
+}
+
+ +

default 语句是可选的。switchcase 都可以使用需要运算才能得到结果的表达式;在 switch 的表达式和 case 的表达式是使用 === 严格相等运算符进行比较的:

+ +
switch(1 + 3){
+    case 2 + 2:
+        yay();
+        break;
+    default:
+        neverhappens();
+}
+
+ +

对象

+ +

JavaScript 中的对象,Object,可以简单理解成“名称-值”对(而不是键值对:现在,ES 2015 的映射表(Map),比对象更接近键值对),不难联想 JavaScript 中的对象与下面这些概念类似:

+ + + +

这样的数据结构设计合理,能应付各类复杂需求,所以被各类编程语言广泛采用。正因为 JavaScript 中的一切(除了核心类型,core object)都是对象,所以 JavaScript 程序必然与大量的散列表查找操作有着千丝万缕的联系,而散列表擅长的正是高速查找。

+ +

“名称”部分是一个 JavaScript 字符串,“值”部分可以是任何 JavaScript 的数据类型——包括对象。这使用户可以根据具体需求,创建出相当复杂的数据结构。

+ +

有两种简单方法可以创建一个空对象:

+ +
var obj = new Object();
+
+ +

和:

+ +
var obj = {};
+
+ +

这两种方法在语义上是相同的。第二种更方便的方法叫作“对象字面量(object literal)”法。这种也是 JSON 格式的核心语法,一般我们优先选择第二种方法。

+ +

“对象字面量”也可以用来在对象实例中定义一个对象:

+ +
var obj = {
+    name: "Carrot",
+    _for: "Max",//'for' 是保留字之一,使用'_for'代替
+    details: {
+        color: "orange",
+        size: 12
+    }
+}
+
+ +

对象的属性可以通过链式(chain)表示方法进行访问:

+ +
obj.details.color; // orange
+obj["details"]["size"]; // 12
+
+ +

下面的例子创建了一个对象原型,Person,和这个原型的实例,You

+ +
function Person(name, age) {
+  this.name = name;
+  this.age = age;
+}
+
+// 定义一个对象
+var You = new Person('You', 24);
+// 我们创建了一个新的 Person,名称是 "You"
+// ("You" 是第一个参数, 24 是第二个参数..)
+
+ +

完成创建后,对象属性可以通过如下两种方式进行赋值和访问:

+ +
// 点表示法(dot notation)
+obj.name = 'Simon';
+var name = obj.name;
+
+ +

和:

+ +
// 括号表示法(bracket notation)
+obj['name'] = 'Simon';
+var name = obj['name'];
+// can use a variable to define a key
+var user = prompt('what is your key?')
+obj[user] = prompt('what is its value?')
+ +

这两种方法在语义上也是相同的。第二种方法的优点在于属性的名称被看作一个字符串,这就意味着它可以在运行时被计算,缺点在于这样的代码有可能无法在后期被解释器优化。它也可以被用来访问某些以预留关键字作为名称的属性的值:

+ +
obj.for = 'Simon'; // 语法错误,因为 for 是一个预留关键字
+obj["for"] = 'Simon'; // 工作正常
+
+ +
+

注意:从 ECMAScript 5 开始,预留关键字可以作为对象的属性名(reserved words may be used as object property names "in the buff")。 这意味着当定义对象字面量时不需要用双引号了。参见 ES5 Spec.

+
+ +

关于对象和原型的详情参见: Object.prototype. 解释对象原型和对象原型链可以参见:继承与原型链

+ +
+

注意:从 ECMAScript 2015 开始,对象键可以在创建时使用括号表示法由变量定义。{[phoneType]: 12345} 可以用来替换 var userPhone = {}; userPhone[phoneType] = 12345 .

+
+ +

数组

+ +

JavaScript 中的数组是一种特殊的对象。它的工作原理与普通对象类似(以数字为属性名,但只能通过[] 来访问),但数组还有一个特殊的属性——length(长度)属性。这个属性的值通常比数组最大索引大 1。

+ +

创建数组的传统方法是:

+ +
var a = new Array();
+a[0] = "dog";
+a[1] = "cat";
+a[2] = "hen";
+a.length; // 3
+
+ +

使用数组字面量(array literal)法更加方便:

+ +
var a = ["dog", "cat", "hen"];
+a.length; // 3
+
+ +

注意,Array.length 并不总是等于数组中元素的个数,如下所示:

+ +
var a = ["dog", "cat", "hen"];
+a[100] = "fox";
+a.length; // 101
+
+ +

记住:数组的长度是比数组最大索引值多一的数。

+ +

如果试图访问一个不存在的数组索引,会得到 undefined

+ +
typeof(a[90]); // undefined
+
+ +

可以通过如下方式遍历一个数组:

+ +
for (var i = 0; i < a.length; i++) {
+    // Do something with a[i]
+}
+
+ +

ES2015 引入了更加简洁的 for...of 循环,可以用它来遍历可迭代对象,例如数组:

+ +
for (const currentValue of a) {
+  // Do something with currentValue
+}
+
+ +

遍历数组的另一种方法是使用 for...in 循环, 然而这并不是遍历数组元素而是数组的索引。注意,如果哪个家伙直接向 Array.prototype 添加了新的属性,使用这样的循环这些属性也同样会被遍历。所以并不推荐使用这种方法遍历数组:

+ +
for (var i in a) {
+  // 操作 a[i]
+}
+
+ +

ECMAScript 5 增加了另一个遍历数组的方法,forEach()

+ +
["dog", "cat", "hen"].forEach(function(currentValue, index, array) {
+  // 操作 currentValue 或者 array[index]
+});
+
+ +

如果想在数组后追加元素,只需要:

+ +
a.push(item);
+ +

除了 forEach()push(),Array(数组)类还自带了许多方法。建议查看 Array 方法的完整文档

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
方法名称描述
a.toString()返回一个包含数组中所有元素的字符串,每个元素通过逗号分隔。
a.toLocaleString()根据宿主环境的区域设置,返回一个包含数组中所有元素的字符串,每个元素通过逗号分隔。
a.concat(item1[, item2[, ...[, itemN]]])返回一个数组,这个数组包含原先 aitem1、item2、……、itemN 中的所有元素。
a.join(sep)返回一个包含数组中所有元素的字符串,每个元素通过指定的 sep 分隔。
a.pop()删除并返回数组中的最后一个元素。
a.push(item1, ..., itemN)item1、item2、……、itemN 追加至数组 a
a.reverse()数组逆序(会更改原数组 a)。
a.shift()删除并返回数组中第一个元素。
a.slice(start, end)返回子数组,以 a[start] 开头,以 a[end] 前一个元素结尾。
a.sort([cmpfn]) +

依据可选的比较函数 cmpfn 进行排序,如果未指定比较函数,则按字符顺序比较(即使被比较元素是数字)。

+
a.splice(start, delcount[, item1[, ...[, itemN]]]) +

start 开始,删除 delcount 个元素,然后插入所有的 item

+
a.unshift(item1[, item2[, ...[, itemN]]]) +

item 插入数组头部,返回数组新长度(考虑 undefined)。

+
+ +

函数

+ +

学习 JavaScript 最重要的就是要理解对象和函数两个部分。最简单的函数就像下面这个这么简单:

+ +
function add(x, y) {
+    var total = x + y;
+    return total;
+}
+
+ +

这个例子包括你需要了解的关于基本函数的所有部分。一个 JavaScript 函数可以包含 0 个或多个已命名的变量。函数体中的表达式数量也没有限制。你可以声明函数自己的局部变量。return 语句在返回一个值并结束函数。如果没有使用 return 语句,或者一个没有值的 return 语句,JavaScript 会返回 undefined

+ +

已命名的参数更像是一个指示而没有其他作用。如果调用函数时没有提供足够的参数,缺少的参数会被 undefined 替代。

+ +
add(); // NaN
+// 不能在 undefined 对象上进行加法操作
+
+ +

你还可以传入多于函数本身需要参数个数的参数:

+ +
add(2, 3, 4); // 5
+ // 将前两个值相加,4 被忽略了
+
+ +

这看上去有点蠢。函数实际上是访问了函数体中一个名为 arguments 的内部对象,这个对象就如同一个类似于数组的对象一样,包括了所有被传入的参数。让我们重写一下上面的函数,使它可以接收任意个数的参数:

+ +
function add() {
+    var sum = 0;
+    for (var i = 0, j = arguments.length; i < j; i++) {
+        sum += arguments[i];
+    }
+    return sum;
+}
+
+add(2, 3, 4, 5); // 14
+
+ +

这跟直接写成 2 + 3 + 4 + 5 也没什么区别。我们还是创建一个求平均数的函数吧:

+ +
function avg() {
+    var sum = 0;
+    for (var i = 0, j = arguments.length; i < j; i++) {
+        sum += arguments[i];
+    }
+    return sum / arguments.length;
+}
+avg(2, 3, 4, 5); // 3.5
+ +

这个就有用多了,但是却有些冗长。为了使代码变短一些,我们可以使用剩余参数来替换arguments的使用。在这方法中,我们可以传递任意数量的参数到函数中同时尽量减少我们的代码。这个剩余参数操作符在函数中以:...variable 的形式被使用,它将包含在调用函数时使用的未捕获整个参数列表到这个变量中。我们同样也可以将 for 循环替换为 for...of 循环来返回我们变量的值。

+ +
function avg(...args) {
+  var sum = 0;
+  for (let value of args) {
+    sum += value;
+  }
+  return sum / args.length;
+}
+
+avg(2, 3, 4, 5); // 3.5
+
+ +
+

在上面这段代码中,所有被传入该函数的参数都被变量 args 所持有。

+ +

需要注意的是,无论“剩余参数操作符”被放置到函数声明的哪里,它都会把除了自己之前的所有参数存储起来。比如函数:function avg(firstValue, ...args) 会把传入函数的第一个值存入 firstValue,其他的参数存入 args。这是虽然一个很有用的语言特性,却也会带来新的问题。avg() 函数只接受逗号分开的参数列表 -- 但是如果你想要获取一个数组的平均值怎么办?一种方法是将函数按照如下方式重写:

+
+ +
function avgArray(arr) {
+    var sum = 0;
+    for (var i = 0, j = arr.length; i < j; i++) {
+        sum += arr[i];
+    }
+    return sum / arr.length;
+}
+avgArray([2, 3, 4, 5]); // 3.5
+
+ +

但如果能重用我们已经创建的那个函数不是更好吗?幸运的是 JavaScript 允许你通过任意函数对象的 apply() 方法来传递给它一个数组作为参数列表。

+ +
avg.apply(null, [2, 3, 4, 5]); // 3.5
+
+ +

传给 apply() 的第二个参数是一个数组,它将被当作 avg() 的参数列表使用,至于第一个参数 null,我们将在后面讨论。这也正说明了一个事实——函数也是对象。

+ +
+

通过使用展开语法,你也可以获得同样的效果。

+ +

比如说:avg(...numbers)

+
+ +

JavaScript 允许你创建匿名函数:

+ +
var avg = function() {
+    var sum = 0;
+    for (var i = 0, j = arguments.length; i < j; i++) {
+        sum += arguments[i];
+    }
+    return sum / arguments.length;
+};
+
+ +

这个函数在语义上与 function avg() 相同。你可以在代码中的任何地方定义这个函数,就像写普通的表达式一样。基于这个特性,有人发明出一些有趣的技巧。与 C 中的块级作用域类似,下面这个例子隐藏了局部变量:

+ +
var a = 1;
+var b = 2;
+(function() {
+    var b = 3;
+    a += b;
+})();
+
+a; // 4
+b; // 2
+
+ +

JavaScript 允许以递归方式调用函数。递归在处理树形结构(比如浏览器 DOM)时非常有用。

+ +
function countChars(elm) {
+    if (elm.nodeType == 3) { // 文本节点
+        return elm.nodeValue.length;
+    }
+    var count = 0;
+    for (var i = 0, child; child = elm.childNodes[i]; i++) {
+        count += countChars(child);
+    }
+    return count;
+}
+
+ +

这里需要说明一个潜在问题——既然匿名函数没有名字,那该怎么递归调用它呢?在这一点上,JavaScript 允许你命名这个函数表达式。你可以命名立即调用的函数表达式(IIFE——Immediately Invoked Function Expression),如下所示:

+ +
var charsInBody = (function counter(elm) {
+    if (elm.nodeType == 3) { // 文本节点
+        return elm.nodeValue.length;
+    }
+    var count = 0;
+    for (var i = 0, child; child = elm.childNodes[i]; i++) {
+        count += counter(child);
+    }
+    return count;
+})(document.body);
+
+ +

如上所提供的函数表达式的名称的作用域仅仅是该函数自身。这允许引擎去做更多的优化,并且这种实现更可读、友好。该名称也显示在调试器和一些堆栈跟踪中,节省了调试时的时间。

+ +

需要注意的是 JavaScript 函数是它们本身的对象——就和 JavaScript 其他一切一样——你可以给它们添加属性或者更改它们的属性,这与前面的对象部分一样。

+ +

自定义对象

+ +
备注:关于 JavaScript 中面向对象编程更详细的信息,请参考 JavaScript 面向对象简介
+ +

在经典的面向对象语言中,对象是指数据和在这些数据上进行的操作的集合。与 C++ 和 Java 不同,JavaScript 是一种基于原型的编程语言,并没有 class 语句,而是把函数用作类。那么让我们来定义一个人名对象,这个对象包括人的姓和名两个域(field)。名字的表示有两种方法:“名 姓(First Last)”或“姓, 名(Last, First)”。使用我们前面讨论过的函数和对象概念,可以像这样完成定义:

+ +
function makePerson(first, last) {
+    return {
+        first: first,
+        last: last
+    };
+}
+function personFullName(person) {
+    return person.first + ' ' + person.last;
+}
+function personFullNameReversed(person) {
+    return person.last + ', ' + person.first;
+}
+
+var s = makePerson('Simon', 'Willison');
+personFullName(s); // "Simon Willison"
+personFullNameReversed(s); // "Willison, Simon"
+ +

上面的写法虽然可以满足要求,但是看起来很麻烦,因为需要在全局命名空间中写很多函数。既然函数本身就是对象,如果需要使一个函数隶属于一个对象,那么不难得到:

+ +
function makePerson(first, last) {
+    return {
+        first: first,
+        last: last,
+        fullName: function() {
+            return this.first + ' ' + this.last;
+        },
+        fullNameReversed: function() {
+            return this.last + ', ' + this.first;
+        }
+    }
+}
+s = makePerson("Simon", "Willison");
+s.fullName(); // "Simon Willison"
+s.fullNameReversed(); // Willison, Simon
+ +

上面的代码里有一些我们之前没有见过的东西:关键字 this。当使用在函数中时,this 指代当前的对象,也就是调用了函数的对象。如果在一个对象上使用点或者方括号来访问属性或方法,这个对象就成了 this。如果并没有使用“点”运算符调用某个对象,那么 this 将指向全局对象(global object)。这是一个经常出错的地方。例如:

+ +
s = makePerson("Simon", "Willison");
+var fullName = s.fullName;
+fullName(); // undefined undefined
+
+ +

当我们调用 fullName() 时,this 实际上是指向全局对象的,并没有名为 firstlast 的全局变量,所以它们两个的返回值都会是 undefined

+ +

下面使用关键字 this 改进已有的 makePerson函数:

+ +
function Person(first, last) {
+    this.first = first;
+    this.last = last;
+    this.fullName = function() {
+        return this.first + ' ' + this.last;
+    }
+    this.fullNameReversed = function() {
+        return this.last + ', ' + this.first;
+    }
+}
+var s = new Person("Simon", "Willison");
+
+ +

我们引入了另外一个关键字:new,它和 this 密切相关。它的作用是创建一个崭新的空对象,然后使用指向那个对象的 this 调用特定的函数。注意,含有 this 的特定函数不会返回任何值,只会修改 this 对象本身。new 关键字将生成的 this 对象返回给调用方,而被 new 调用的函数称为构造函数。习惯的做法是将这些函数的首字母大写,这样用 new 调用他们的时候就容易识别了。

+ +

不过,这个改进的函数还是和上一个例子一样,在单独调用fullName() 时,会产生相同的问题。

+ +

我们的 Person 对象现在已经相当完善了,但还有一些不太好的地方。每次我们创建一个 Person 对象的时候,我们都在其中创建了两个新的函数对象——如果这个代码可以共享不是更好吗?

+ +
function personFullName() {
+    return this.first + ' ' + this.last;
+}
+function personFullNameReversed() {
+    return this.last + ', ' + this.first;
+}
+function Person(first, last) {
+    this.first = first;
+    this.last = last;
+    this.fullName = personFullName;
+    this.fullNameReversed = personFullNameReversed;
+}
+
+ +

这种写法的好处是,我们只需要创建一次方法函数,在构造函数中引用它们。那是否还有更好的方法呢?答案是肯定的。

+ +
function Person(first, last) {
+    this.first = first;
+    this.last = last;
+}
+Person.prototype.fullName = function() {
+    return this.first + ' ' + this.last;
+}
+Person.prototype.fullNameReversed = function() {
+    return this.last + ', ' + this.first;
+}
+
+ +

Person.prototype 是一个可以被Person的所有实例共享的对象。它是一个名叫原型链(prototype chain)的查询链的一部分:当你试图访问 Person 某个实例(例如上个例子中的s)一个没有定义的属性时,解释器会首先检查这个 Person.prototype 来判断是否存在这样一个属性。所以,任何分配给 Person.prototype 的东西对通过 this 对象构造的实例都是可用的。

+ +

这个特性功能十分强大,JavaScript 允许你在程序中的任何时候修改原型(prototype)中的一些东西,也就是说你可以在运行时(runtime)给已存在的对象添加额外的方法:

+ +
s = new Person("Simon", "Willison");
+s.firstNameCaps();  // TypeError on line 1: s.firstNameCaps is not a function
+
+Person.prototype.firstNameCaps = function() {
+    return this.first.toUpperCase()
+}
+s.firstNameCaps(); // SIMON
+
+ +

有趣的是,你还可以给 JavaScript 的内置函数原型(prototype)添加东西。让我们给 String 添加一个方法用来返回逆序的字符串:

+ +
var s = "Simon";
+s.reversed(); // TypeError on line 1: s.reversed is not a function
+
+String.prototype.reversed = function() {
+    var r = "";
+    for (var i = this.length - 1; i >= 0; i--) {
+        r += this[i];
+    }
+    return r;
+}
+s.reversed(); // nomiS
+
+ +

定义新方法也可以在字符串字面量上用(string literal)。

+ +
"This can now be reversed".reversed(); // desrever eb won nac sihT
+
+ +

正如我前面提到的,原型组成链的一部分。那条链的根节点是 Object.prototype,它包括 toString() 方法——将对象转换成字符串时调用的方法。这对于调试我们的 Person 对象很有用:

+ +
var s = new Person("Simon", "Willison");
+s; // [object Object]
+
+Person.prototype.toString = function() {
+    return '<Person: ' + this.fullName() + '>';
+}
+s.toString(); // <Person: Simon Willison>
+
+ +

你是否还记得之前我们说的 avg.apply() 中的第一个参数 null?现在我们可以回头看看这个东西了。apply() 的第一个参数应该是一个被当作 this 来看待的对象。下面是一个 new 方法的简单实现:

+ +
function trivialNew(constructor, ...args) {
+    var o = {}; // 创建一个对象
+    constructor.apply(o, args);
+    return o;
+}
+
+ +

这并不是 new 的完整实现,因为它没有创建原型(prototype)链。想举例说明 new 的实现有些困难,因为你不会经常用到这个,但是适当了解一下还是很有用的。在这一小段代码里,...args(包括省略号)叫作剩余参数(rest arguments)。如名所示,这个东西包含了剩下的参数。

+ +

因此,调用

+ +
var bill = trivialNew(Person, "William", "Orange");
+ +

可认为和调用如下语句是等效的

+ +
var bill = new Person("William", "Orange");
+ +

apply() 有一个姐妹函数,名叫 call,它也可以允许你设置 this,但它带有一个扩展的参数列表而不是一个数组。

+ +
function lastNameCaps() {
+    return this.last.toUpperCase();
+}
+var s = new Person("Simon", "Willison");
+lastNameCaps.call(s);
+// 和以下方式等价
+s.lastNameCaps = lastNameCaps;
+s.lastNameCaps();
+
+ +

内部函数

+ +

JavaScript 允许在一个函数内部定义函数,这一点我们在之前的 makePerson() 例子中也见过。关于 JavaScript 中的嵌套函数,一个很重要的细节是,它们可以访问父函数作用域中的变量:

+ +
function parentFunc() {
+  var a = 1;
+
+  function nestedFunc() {
+    var b = 4; // parentFunc 无法访问 b
+    return a + b;
+  }
+  return nestedFunc(); // 5
+}
+ +

如果某个函数依赖于其他的一两个函数,而这一两个函数对你其余的代码没有用处,你可以将它们嵌套在会被调用的那个函数内部,这样做可以减少全局作用域下的函数的数量,这有利于编写易于维护的代码。

+ +

这也是一个减少使用全局变量的好方法。当编写复杂代码时,程序员往往试图使用全局变量,将值共享给多个函数,但这样做会使代码很难维护。内部函数可以共享父函数的变量,所以你可以使用这个特性把一些函数捆绑在一起,这样可以有效地防止“污染”你的全局命名空间——你可以称它为“局部全局(local global)”。虽然这种方法应该谨慎使用,但它确实很有用,应该掌握。

+ +

闭包

+ +

闭包是 JavaScript 中最强大的抽象概念之一——但它也是最容易造成困惑的。它究竟是做什么的呢?

+ +
function makeAdder(a) {
+  return function(b) {
+    return a + b;
+  }
+}
+var add5 = makeAdder(5);
+var add20 = makeAdder(20);
+add5(6); // ?
+add20(7); // ?
+
+ +

makeAdder 这个名字本身,便应该能说明函数是用来做什么的:它会用一个参数来创建一个新的“adder”函数,再用另一个参数来调用被创建的函数时,makeAdder 会将一前一后两个参数相加。

+ +

从被创建的函数的视角来看的话,这两个参数的来源问题会更显而易见:新函数自带一个参数——在新函数被创建时,便钦定、钦点了前一个参数(如上方代码中的 a、5 和 20,参考 makeAdder 的结构,它应当位于新函数外部);新函数被调用时,又接收了后一个参数(如上方代码中的 b、6 和 7,位于新函数内部)。最终,新函数被调用的时候,前一个参数便会和由外层函数传入的后一个参数相加。

+ +

这里发生的事情和前面介绍过的内嵌函数十分相似:一个函数被定义在了另外一个函数的内部,内部函数可以访问外部函数的变量。唯一的不同是,外部函数已经返回了,那么常识告诉我们局部变量“应该”不再存在。但是它们却仍然存在——否则 adder 函数将不能工作。也就是说,这里存在 makeAdder 的局部变量的两个不同的“副本”——一个是 a 等于 5,另一个是 a 等于 20。那些函数的运行结果就如下所示:

+ +
x(6); // 返回 11
+y(7); // 返回 27
+
+ +

下面来说说,到底发生了什么了不得的事情。每当 JavaScript 执行一个函数时,都会创建一个作用域对象(scope object),用来保存在这个函数中创建的局部变量。它使用一切被传入函数的变量进行初始化(初始化后,它包含一切被传入函数的变量)。这与那些保存的所有全局变量和函数的全局对象(global object)相类似,但仍有一些很重要的区别:第一,每次函数被执行的时候,就会创建一个新的,特定的作用域对象;第二,与全局对象(如浏览器的 window 对象)不同的是,你不能从 JavaScript 代码中直接访问作用域对象,也没有 可以遍历当前作用域对象中的属性 的方法。

+ +

所以,当调用 makeAdder 时,解释器创建了一个作用域对象,它带有一个属性:a,这个属性被当作参数传入 makeAdder 函数。然后 makeAdder 返回一个新创建的函数(暂记为 adder)。通常,JavaScript 的垃圾回收器会在这时回收 makeAdder 创建的作用域对象(暂记为 b),但是,makeAdder 的返回值,新函数 adder,拥有一个指向作用域对象 b 的引用。最终,作用域对象 b 不会被垃圾回收器回收,直到没有任何引用指向新函数 adder

+ +

作用域对象组成了一个名为作用域链(scope chain)的(调用)链。它和 JavaScript 的对象系统使用的原型(prototype)链相类似。

+ +

一个闭包,就是 一个函数 与其 被创建时所带有的作用域对象 的组合。闭包允许你保存状态——所以,它们可以用来代替对象。这个 StackOverflow 帖子里有一些关于闭包的详细介绍。

diff --git a/files/zh-cn/web/javascript/about_javascript/index.html b/files/zh-cn/web/javascript/about_javascript/index.html new file mode 100644 index 0000000000..94b366cd08 --- /dev/null +++ b/files/zh-cn/web/javascript/about_javascript/index.html @@ -0,0 +1,59 @@ +--- +title: 关于 JavaScript +slug: Web/JavaScript/About_JavaScript +tags: + - JavaScript + - 入门介绍 +translation_of: Web/JavaScript/About_JavaScript +--- +
{{JsSidebar()}}
+ +

什么是 JavaScript?

+ +

JavaScript® (通常简写为JS)是一种轻量的、解释性的、面向对象的头等函数语言,其最广为人知的应用是作为网页的脚本语言,但同时它也在很多非浏览器环境下使用。JS是一种动态的基于原型和多范式的脚本语言,支持面向对象、命令式和函数式的编程风格。

+ +

JavaScript运行在网页的客户端,能被用来设计和编程网页在事件发生时的行为。JavaScript不仅易学而且强大,因此广泛用于对网页的控制。

+ +

与流行的误解相反,JavaScript 并不是“解释性 Java”。简单来说,JavaScript 是一个动态脚本语言,支持 基于原型的 对象构造。其基本语法被设计地与 Java 和 C++ 接近,来减少学习语言所需要的新概念。语言结构,如条件语句(if)、循环(for,while)、分支(switch)、异常捕获(try...catch)等和这些语言一致或者很接近。

+ +

JavaScript 既是一个 面向过程的语言 又是一个 面向对象的语言。在 JavaScript 中,通过在运行时给空对象附加方法和属性来创建对象,与编译语言如 C++ 和 Java 中常见的通过语法来定义类相反。对象构造后,它可以用作是创建相似对象的原型。

+ +

JavaScript 的动态特性包括运行时构造对象、可变参数列表、函数变量、动态脚本执行(通过 eval)、对象内枚举(通过 for ... in)和源码恢复(JavaScript 程序可以将函数反编译回源代码)。

+ +

如果您需要了解更多 JavaScript 编程信息,请参见下方的 JavaScript 资源 链接。

+ +

有哪些 JavaScript 的实现?

+ +

mozilla.org 上托管了两个 JavaScript 实现。首个 JavaScript 由网景公司的 Brendan Eich 创建,并不断地更新以符合 ECMA-262 Edition 5 及其之后的标准版本。这个引擎,代号 SpiderMonkey ,是由 C/C++ 语言开发的。而 Rhino 引擎,主要由 Norris Boyd(同样也是在网景公司)创建,则是一个 Java 语言开发的 JavaScript 实现。与 SpiderMonkey 类似,Rhino 符合 ECMA-262 Edition 5 标准。

+ +

有很多优化技术如 TraceMonkey (Firefox 3.5)、JägerMonkey (Firefox 4) 和 IonMonkey 被不断添加到了 SpiderMonkey JavaScript 引擎。并且提升JavaScript执行效率的工作一直在进行。

+ +

除了以上实现,还有其他一些流行的 JavaScript 引擎,如:

+ + + +

每个 mozilla.org 的 JavaScript 引擎都提供了 公用API使程序开发者能将其JavaScript嵌入自己的软件中。目前最常见的 JavaScript 宿主环境是网页浏览器。浏览器一般通过 API 创建“宿主对象”来负责将DOM 反射到 JavaScript 中。

+ +

另一个常见的 JavaScript 应用是作为服务端脚本语言。JavaScript 服务器提供宿主对象代表 HTTP 请求和响应,随后可以通过 JavaScript 程序来动态的生成 Web 页面。Node.js便是一个流行的例子。

+ +

JavaScript 资源

+ +
+
SpiderMonkey
+
Mozilla使用C/C++引擎实现JavaScript(又称为SpiderMonkey),以及如何在应用中嵌入使用的相关信息。
+
+ +
+
Rhino
+
Rhino(Java 语言实现的 JavaScript)的相关信息。
+
语言资源
+
已经公布的 JavaScript 标准。
+
重新认识 JavaScript
+
JavaScript 指南JavaScript 参考
+
JavaScript®是Oracle于美国和其他国家注册和拥有的商标。
+
diff --git a/files/zh-cn/web/javascript/closures/index.html b/files/zh-cn/web/javascript/closures/index.html new file mode 100644 index 0000000000..4c84f51dd9 --- /dev/null +++ b/files/zh-cn/web/javascript/closures/index.html @@ -0,0 +1,409 @@ +--- +title: 闭包 +slug: Web/JavaScript/Closures +tags: + - ES5 + - JavaScript + - 中级的 + - 手册 + - 指南 + - 闭包 +translation_of: Web/JavaScript/Closures +--- +
{{jsSidebar("Intermediate")}}
+ +

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

+ +

词法作用域

+ +

请看下面的代码:

+ +
+
function init() {
+    var name = "Mozilla"; // name 是一个被 init 创建的局部变量
+    function displayName() { // displayName() 是内部函数,一个闭包
+        alert(name); // 使用了父函数中声明的变量
+    }
+    displayName();
+}
+init();
+
+ +

init() 创建了一个局部变量 name 和一个名为 displayName() 的函数。displayName() 是定义在 init() 里的内部函数,并且仅在 init() 函数体内可用。请注意,displayName() 没有自己的局部变量。然而,因为它可以访问到外部函数的变量,所以 displayName() 可以使用父函数 init() 中声明的变量 name

+ +

使用这个 JSFiddle 链接运行该代码后发现, displayName() 函数内的 alert() 语句成功显示出了变量 name 的值(该变量在其父函数中声明)。这个词法作用域的例子描述了分析器如何在函数嵌套的情况下解析变量名。词法(lexical)一词指的是,词法作用域根据源代码中声明变量的位置来确定该变量在何处可用。嵌套函数可访问声明于它们外部作用域的变量。

+ +

闭包

+ +

现在来考虑以下例子 :

+ +
function makeFunc() {
+    var name = "Mozilla";
+    function displayName() {
+        alert(name);
+    }
+    return displayName;
+}
+
+var myFunc = makeFunc();
+myFunc();
+ +

运行这段代码的效果和之前 init() 函数的示例完全一样。其中不同的地方(也是有意思的地方)在于内部函数 displayName() 在执行前,从外部函数返回。

+ +

第一眼看上去,也许不能直观地看出这段代码能够正常运行。在一些编程语言中,一个函数中的局部变量仅存在于此函数的执行期间。一旦 makeFunc() 执行完毕,你可能会认为 name 变量将不能再被访问。然而,因为代码仍按预期运行,所以在 JavaScript 中情况显然与此不同。

+ +

原因在于,JavaScript中的函数会形成了闭包。 闭包是由函数以及声明该函数的词法环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。在本例子中,myFunc 是执行 makeFunc 时创建的 displayName 函数实例的引用。displayName 的实例维持了一个对它的词法环境(变量 name 存在于其中)的引用。因此,当 myFunc 被调用时,变量 name 仍然可用,其值 Mozilla 就被传递到alert中。

+ +

下面是一个更有意思的示例 — 一个 makeAdder 函数:

+ +
function makeAdder(x) {
+  return function(y) {
+    return x + y;
+  };
+}
+
+var add5 = makeAdder(5);
+var add10 = makeAdder(10);
+
+console.log(add5(2));  // 7
+console.log(add10(2)); // 12
+
+ +

在这个示例中,我们定义了 makeAdder(x) 函数,它接受一个参数 x ,并返回一个新的函数。返回的函数接受一个参数 y,并返回x+y的值。

+ +

从本质上讲,makeAdder 是一个函数工厂 — 他创建了将指定的值和它的参数相加求和的函数。在上面的示例中,我们使用函数工厂创建了两个新函数 — 一个将其参数和 5 求和,另一个和 10 求和。

+ +

add5add10 都是闭包。它们共享相同的函数定义,但是保存了不同的词法环境。在 add5 的环境中,x 为 5。而在 add10 中,x 则为 10。

+ +

实用的闭包

+ +

闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。

+ +

因此,通常你使用只有一个方法的对象的地方,都可以使用闭包。

+ +

在 Web 中,你想要这样做的情况特别常见。大部分我们所写的 JavaScript 代码都是基于事件的 — 定义某种行为,然后将其添加到用户触发的事件之上(比如点击或者按键)。我们的代码通常作为回调:为响应事件而执行的函数。

+ +

假如,我们想在页面上添加一些可以调整字号的按钮。一种方法是以像素为单位指定 body 元素的 font-size,然后通过相对的 em 单位设置页面中其它元素(例如header)的字号:

+ +
body {
+  font-family: Helvetica, Arial, sans-serif;
+  font-size: 12px;
+}
+
+h1 {
+  font-size: 1.5em;
+}
+
+h2 {
+  font-size: 1.2em;
+}
+
+ +

我们的文本尺寸调整按钮可以修改 body 元素的 font-size 属性,由于我们使用相对单位,页面中的其它元素也会相应地调整。

+ +

以下是 JavaScript:

+ +
function makeSizer(size) {
+  return function() {
+    document.body.style.fontSize = size + 'px';
+  };
+}
+
+var size12 = makeSizer(12);
+var size14 = makeSizer(14);
+var size16 = makeSizer(16);
+
+ +

size12size14size16 三个函数将分别把 body 文本调整为 12,14,16 像素。我们可以将它们分别添加到按钮的点击事件上。如下所示:

+ +
document.getElementById('size-12').onclick = size12;
+document.getElementById('size-14').onclick = size14;
+document.getElementById('size-16').onclick = size16;
+
+ +
<a href="#" id="size-12">12</a>
+<a href="#" id="size-14">14</a>
+<a href="#" id="size-16">16</a>
+
+ +

{{JSFiddleEmbed("https://jsfiddle.net/cubr4hs0/","","200")}}

+ +

用闭包模拟私有方法

+ +

编程语言中,比如 Java,是支持将方法声明为私有的,即它们只能被同一个类中的其它方法所调用。

+ +

而 JavaScript 没有这种原生支持,但我们可以使用闭包来模拟私有方法。私有方法不仅仅有利于限制对代码的访问:还提供了管理全局命名空间的强大能力,避免非核心的方法弄乱了代码的公共接口部分。

+ +

下面的示例展现了如何使用闭包来定义公共函数,并令其可以访问私有函数和变量。这个方式也称为 模块模式(module pattern):

+ +
var Counter = (function() {
+  var privateCounter = 0;
+  function changeBy(val) {
+    privateCounter += val;
+  }
+  return {
+    increment: function() {
+      changeBy(1);
+    },
+    decrement: function() {
+      changeBy(-1);
+    },
+    value: function() {
+      return privateCounter;
+    }
+  }
+})();
+
+console.log(Counter.value()); /* logs 0 */
+Counter.increment();
+Counter.increment();
+console.log(Counter.value()); /* logs 2 */
+Counter.decrement();
+console.log(Counter.value()); /* logs 1 */
+
+ +

在之前的示例中,每个闭包都有它自己的词法环境;而这次我们只创建了一个词法环境,为三个函数所共享:Counter.increment,Counter.decrementCounter.value

+ +

该共享环境创建于一个立即执行的匿名函数体内。这个环境中包含两个私有项:名为 privateCounter 的变量和名为 changeBy 的函数。这两项都无法在这个匿名函数外部直接访问。必须通过匿名函数返回的三个公共函数访问。

+ +

这三个公共函数是共享同一个环境的闭包。多亏 JavaScript 的词法作用域,它们都可以访问 privateCounter 变量和 changeBy 函数。

+ +
+

你应该注意到我们定义了一个匿名函数,用于创建一个计数器。我们立即执行了这个匿名函数,并将他的值赋给了变量Counter。我们可以把这个函数储存在另外一个变量makeCounter中,并用他来创建多个计数器。

+
+ +
var makeCounter = function() {
+  var privateCounter = 0;
+  function changeBy(val) {
+    privateCounter += val;
+  }
+  return {
+    increment: function() {
+      changeBy(1);
+    },
+    decrement: function() {
+      changeBy(-1);
+    },
+    value: function() {
+      return privateCounter;
+    }
+  }
+};
+
+var Counter1 = makeCounter();
+var Counter2 = makeCounter();
+console.log(Counter1.value()); /* logs 0 */
+Counter1.increment();
+Counter1.increment();
+console.log(Counter1.value()); /* logs 2 */
+Counter1.decrement();
+console.log(Counter1.value()); /* logs 1 */
+console.log(Counter2.value()); /* logs 0 */
+
+ +

请注意两个计数器 Counter1 和 Counter2 是如何维护它们各自的独立性的。每个闭包都是引用自己词法作用域内的变量 privateCounter 。

+ +

每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境。然而在一个闭包内对变量的修改,不会影响到另外一个闭包中的变量。

+ +
+

以这种方式使用闭包,提供了许多与面向对象编程相关的好处 —— 特别是数据隐藏和封装。

+
+ +

在循环中创建闭包:一个常见错误

+ +

在 ECMAScript 2015 引入 let 关键字 之前,在循环中有一个常见的闭包创建问题。参考下面的示例:

+ +
<p id="help">Helpful notes will appear here</p>
+<p>E-mail: <input type="text" id="email" name="email"></p>
+<p>Name: <input type="text" id="name" name="name"></p>
+<p>Age: <input type="text" id="age" name="age"></p>
+
+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    var item = helpText[i];
+    document.getElementById(item.id).onfocus = function() {
+      showHelp(item.help);
+    }
+  }
+}
+
+setupHelp();
+
+ +

{{JSFiddleEmbed("https://jsfiddle.net/51brm6ps/", "", 200)}}

+ +

数组 helpText 中定义了三个有用的提示信息,每一个都关联于对应的文档中的input 的 ID。通过循环这三项定义,依次为相应input添加了一个 onfocus  事件处理函数,以便显示帮助信息。

+ +

运行这段代码后,您会发现它没有达到想要的效果。无论焦点在哪个input上,显示的都是关于年龄的信息。

+ +

原因是赋值给 onfocus 的是闭包。这些闭包是由他们的函数定义和在 setupHelp 作用域中捕获的环境所组成的。这三个闭包在循环中被创建,但他们共享了同一个词法作用域,在这个作用域中存在一个变量item。这是因为变量item使用var进行声明,由于变量提升,所以具有函数作用域。当onfocus的回调执行时,item.help的值被决定。由于循环在事件触发之前早已执行完毕,变量对象item(被三个闭包所共享)已经指向了helpText的最后一项。

+ +

解决这个问题的一种方案是使用更多的闭包:特别是使用前面所述的函数工厂:

+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function makeHelpCallback(help) {
+  return function() {
+    showHelp(help);
+  };
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    var item = helpText[i];
+    document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
+  }
+}
+
+setupHelp();
+
+ +

{{JSFiddleEmbed("https://jsfiddle.net/v7gjv/12185/", "", 300)}}

+ +

这段代码可以如我们所期望的那样工作。所有的回调不再共享同一个环境, makeHelpCallback 函数为每一个回调创建一个新的词法环境。在这些环境中,help 指向 helpText 数组中对应的字符串。

+ +

另一种方法使用了匿名闭包:

+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    (function() {
+       var item = helpText[i];
+       document.getElementById(item.id).onfocus = function() {
+         showHelp(item.help);
+       }
+    })(); // 马上把当前循环项的item与事件回调相关联起来
+  }
+}
+
+setupHelp();
+ +

如果不想使用过多的闭包,你可以用ES2015引入的let关键词:

+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    let item = helpText[i];
+    document.getElementById(item.id).onfocus = function() {
+      showHelp(item.help);
+    }
+  }
+}
+
+setupHelp();
+ +

这个例子使用let而不是var,因此每个闭包都绑定了块作用域的变量,这意味着不再需要额外的闭包。

+ +

另一个可选方案是使用 forEach()来遍历helpText数组并给每一个<p>添加一个监听器,如下所示:

+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  helpText.forEach(function(text) {
+    document.getElementById(text.id).onfocus = function() {
+      showHelp(text.help);
+    }
+  });
+}
+
+setupHelp();
+ +

性能考量

+ +

如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。

+ +

例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。原因是这将导致每次构造器被调用时,方法都会被重新赋值一次(也就是说,对于每个对象的创建,方法都会被重新赋值)。

+ +

考虑以下示例:

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+  this.getName = function() {
+    return this.name;
+  };
+
+  this.getMessage = function() {
+    return this.message;
+  };
+}
+
+ +

在上面的代码中,我们并没有利用到闭包的好处,因此可以避免使用闭包。修改成如下:

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+}
+MyObject.prototype = {
+  getName: function() {
+    return this.name;
+  },
+  getMessage: function() {
+    return this.message;
+  }
+};
+
+
+ +

但我们不建议重新定义原型。可改成如下例子:

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+}
+MyObject.prototype.getName = function() {
+  return this.name;
+};
+MyObject.prototype.getMessage = function() {
+  return this.message;
+};
+
+
+ +

在前面的两个示例中,继承的原型可以为所有对象共享,不必在每一次创建对象时定义方法。参见 对象模型的细节 一章可以了解更为详细的信息。

diff --git a/files/zh-cn/web/javascript/data_structures/index.html b/files/zh-cn/web/javascript/data_structures/index.html new file mode 100644 index 0000000000..5b3e069800 --- /dev/null +++ b/files/zh-cn/web/javascript/data_structures/index.html @@ -0,0 +1,321 @@ +--- +title: JavaScript 数据类型和数据结构 +slug: Web/JavaScript/Data_structures +tags: + - JavaScript + - 初学者 + - 数据结构 + - 类型 +translation_of: Web/JavaScript/Data_structures +--- +
{{jsSidebar("More")}}
+ +

编程语言都具有内建的数据结构,但各种编程语言的数据结构常有不同之处。本文试图列出 JavaScript 语言中内建的数据结构及其属性,它们可以用来构建其他的数据结构;同时尽可能地描述与其他语言的不同之处。

+ +

动态类型

+ +

JavaScript 是一种弱类型或者说动态语言。这意味着你不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。这也意味着你可以使用同一个变量保存不同类型的数据:

+ +
var foo = 42;    // foo is a Number now
+foo = "bar"; // foo is a String now
+foo = true;  // foo is a Boolean now
+
+ +

数据类型

+ +

最新的 ECMAScript 标准定义了 9 种数据类型:

+ + + +

记住 typeof 操作符的唯一目的就是检查数据类型,如果我们希望检查任何从 Object 派生出来的结构类型,使用 typeof 是不起作用的,因为总是会得到 "object"。检查 Object 种类的合适方式是使用 {{Glossary("instanceof")}} 关键字。但即使这样也存在误差。

+ +

原始值( primitive values )

+ +

除 Object 以外的所有类型都是不可变的(值本身无法被改变)。例如,与 C 语言不同,JavaScript 中字符串是不可变的(译注:如,JavaScript 中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变)。我们称这些类型的值为“原始值”。

+ +

布尔类型

+ +

布尔表示一个逻辑实体,可以有两个值:truefalse

+ +

Null 类型

+ +

Null 类型只有一个值: null,更多详情可查看 {{jsxref("null")}} 和 {{Glossary("Null")}} 。

+ +

Undefined 类型

+ +

一个没有被赋值的变量会有个默认值 undefined,更多详情可查看 {{jsxref("undefined")}} 和 {{Glossary("Undefined")}}。

+ +

数字类型

+ +

根据 ECMAScript 标准,JavaScript 中只有一种数字类型:基于 IEEE 754 标准的双精度 64 位二进制格式的值(-(253 -1) 到 253 -1)。它并没有为整数给出一种特定的类型。除了能够表示浮点数外,还有一些带符号的值:+Infinity-InfinityNaN (非数值,Not-a-Number)。

+ +

要检查值是否大于或小于 +/-Infinity,你可以使用常量 {{jsxref("Number.MAX_VALUE")}} 和 {{jsxref("Number.MIN_VALUE")}}。另外在 ECMAScript 6 中,你也可以通过 {{jsxref("Number.isSafeInteger()")}} 方法还有 {{jsxref("Number.MAX_SAFE_INTEGER")}} 和 {{jsxref("Number.MIN_SAFE_INTEGER")}} 来检查值是否在双精度浮点数的取值范围内。 超出这个范围,JavaScript 中的数字不再安全了,也就是只有 second mathematical interger 可以在 JavaScript 数字类型中正确表现。

+ +

数字类型中只有一个整数有两种表示方法: 0 可表示为 -0 和 +0("0" 是 +0 的简写)。 在实践中,这也几乎没有影响。 例如 +0 === -0 为真。 但是,你可能要注意除以0的时候:

+ +
42 / +0; // Infinity
+42 / -0; // -Infinity
+
+ +

尽管一个数字常常仅代表它本身的值,但JavaScript提供了一些位运算符。 这些位运算符和一个单一数字通过位操作可以用来表现一些布尔值。然而自从 JavaScript 提供其他的方式来表示一组布尔值(如一个布尔值数组或一个布尔值分配给命名属性的对象)后,这种方式通常被认为是不好的。位操作也容易使代码难以阅读,理解和维护, 在一些非常受限的情况下,可能需要用到这些技术,比如试图应付本地存储的存储限制。 位操作只应该是用来优化尺寸的最后选择。

+ +

BigInt 类型

+ +

{{jsxref("BigInt")}}类型是 JavaScript 中的一个基础的数值类型,可以用任意精度表示整数。使用 BigInt,您可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。BigInt是通过在整数末尾附加 或调用构造函数来创建的。

+ +

通过使用常量{{jsxref("Number.MAX_SAFE_INTEGER")}},您可以获得可以用数字递增的最安全的值。通过引入 BigInt,您可以操作超过{{jsxref("Number.MAX_SAFE_INTEGER")}}的数字。您可以在下面的示例中观察到这一点,其中递增{{jsxref("Number.MAX_SAFE_INTEGER")}}会返回预期的结果:

+ +
> const x = 2n ** 53n;
+9007199254740992n
+> const y = x + 1n;
+9007199254740993n
+
+ +

可以对BigInt使用运算符+*-**%,就像对数字一样。BigInt 严格来说并不等于一个数字,但它是松散的。

+ +

在将BigInt转换为Boolean时,它的行为类似于一个数字:if||&&Boolean 和!。

+ +

BigInt不能与数字互换操作。否则,将抛出{{jsxref("TypeError")}}。

+ +

字符串类型

+ +

JavaScript的字符串类型用于表示文本数据。它是一组16位的无符号整数值的“元素”。在字符串中的每个元素占据了字符串的位置。第一个元素的索引为0,下一个是索引1,依此类推。字符串的长度是它的元素的数量。

+ +

不同于类 C 语言,JavaScript 字符串是不可更改的。这意味着字符串一旦被创建,就不能被修改。但是,可以基于对原始字符串的操作来创建新的字符串。例如:

+ + + +

注意代码中的“字符串类型”!

+ +

可以使用字符串来表达复杂的数据。以下是一些很好的性质:

+ + + +

使用约定,字符串一般可以用来表达任何数据结构。这不是一个好主意。例如,使用一个分隔符,可以模拟一个列表(而 JavaScript 数组可能更适合)。不幸的是,当分隔符用于列表中的元素时,列表就会被破坏。 可以选择转义字符,等等。所有这些都需要约定,并造成不必要的维护负担。

+ +

表达文本数据和符号数据时候推荐使用字符串。当表达复杂的数据时,使用字符串解析和适当的缩写。

+ +

符号类型

+ +

符号(Symbols)是ECMAScript 第6版新定义的。符号类型是唯一的并且是不可修改的, 并且也可以用来作为Object的key的值(如下). 在某些语言当中也有类似的原子类型(Atoms). 你也可以认为为它们是C里面的枚举类型. 更多细节请看 {{Glossary("Symbol")}} 和 {{jsxref("Symbol")}} 。

+ +

对象

+ +

在计算机科学中, 对象是指内存中的可以被 {{Glossary("Identifier", "标识符")}}引用的一块区域.

+ +

属性

+ +

在 Javascript 里,对象可以被看作是一组属性的集合。用对象字面量语法来定义一个对象时,会自动初始化一组属性。(也就是说,你定义一个var a = "Hello",那么a本身就会有a.substring这个方法,以及a.length这个属性,以及其它;如果你定义了一个对象,var a = {},那么a就会自动有a.hasOwnProperty及a.constructor等属性和方法。)而后,这些属性还可以被增减。属性的值可以是任意类型,包括具有复杂数据结构的对象。属性使用键来标识,它的键值可以是一个字符串或者符号值(Symbol)。

+ +

ECMAScript定义的对象中有两种属性:数据属性和访问器属性。

+ +

数据属性

+ +

数据属性是键值对,并且每个数据属性拥有下列特性:

+ +

数据属性的特性(Attributes of a data property)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
特性数据类型描述默认值
[[Value]]任何Javascript类型包含这个属性的数据值。undefined
[[Writable]]Boolean如果该值为 false,则该属性的 [[Value]] 特性 不能被改变。false
[[Enumerable]]Boolean如果该值为 true,则该属性可以用 for...in 循环来枚举。false
[[Configurable]]Boolean如果该值为 false,则该属性不能被删除,并且 除了 [[Value]] 和 [[Writable]] 以外的特性都不能被改变。false
+ + + + + + + + + + + + + + + + + + + + + + + + + +
过时的属性(在ECMAScript 3定义的, 在ECMAScript 5被重命名)
属性类型描述
Read-onlyBooleanES5 [[Writable]] 属性的反状态(Reversed state)
DontEnumBooleanES5 [[Enumerable]]  属性的反状态
DontDeleteBooleanES5 [[Configurable]] 属性的反状态
+ +

访问器属性

+ +

访问器属性有一个或两个访问器函数 (get 和 set) 来存取数值,并且有以下特性:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
一个访问器属性的特性
特性类型描述默认值
[[Get]]函数对象或者 undefined该函数使用一个空的参数列表,能够在有权访问的情况下读取属性值。另见 getundefined
[[Set]]函数对象或者 undefined该函数有一个参数,用来写入属性值,另见 setundefined
[[Enumerable]]Boolean如果该值为 true,则该属性可以用 for...in 循环来枚举。false
[[Configurable]]Boolean如果该值为 false,则该属性不能被删除,并且不能被转变成一个数据属性。false
+ +
+

注意:这些特性只有 JavaScript 引擎才用到,因此你不能直接访问它们。所以特性被放在两对方括号中,而不是一对。

+
+ +

"标准的" 对象, 和函数

+ +

一个 Javascript 对象就是键和值之间的映射.。键是一个字符串(或者 {{jsxref("Symbol")}}) ,值可以是任意类型的值。 这使得对象非常符合 哈希表

+ +

函数是一个附带可被调用功能的常规对象。

+ +

日期

+ +

当你想要显示日期时,毋庸置疑,使用内建的 Date 对象。

+ +

有序集: 数组和类型数组

+ +

数组是一种使用整数作为键(integer-key-ed)属性和长度(length)属性之间关联的常规对象。此外,数组对象还继承了 Array.prototype 的一些操作数组的便捷方法。例如, indexOf (搜索数组中的一个值) or push (向数组中添加一个元素),等等。 这使得数组是表示列表或集合的最优选择。

+ +

类型数组(Typed Arrays)是ECMAScript Edition 6中新定义的 JavaScript 内建对象,提供了一个基本的二进制数据缓冲区的类数组视图。下面的表格能帮助你找到对等的 C 语言数据类型:

+ +

{{page("/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray", "TypedArray_objects", "", 0, 3)}}

+ +

键控集: Maps, Sets, WeakMaps, WeakSets

+ +

这些数据结构把对象的引用当作键,其在ECMAScript第6版中有介绍。当 {{jsxref("Map")}} 和 {{jsxref("WeakMap")}} 把一个值和对象关联起来的时候, {{jsxref("Set")}} 和 {{jsxref("WeakSet")}} 表示一组对象。 Map和WeakMaps之间的差别在于,在前者中,对象键是可枚举的。这允许垃圾收集器优化后面的枚举(This allows garbage collection optimizations in the latter case)。

+ +

在纯ECMAScript 5下可以实现Maps和Sets。然而,因为对象并不能进行比较(就对象“小于”示例来讲),所以查询必定是线性的。他们本地实现(包括WeakMaps)查询所花费的时间可能是对数增长。

+ +

通常,可以通过直接在对象上设置属性或着使用data-*属性,来绑定数据到DOM节点。然而缺陷是在任何的脚本里,数据都运行在同样的上下文中。Maps和WeakMaps方便将数据私密的绑定到一个对象。 

+ +

结构化数据: JSON

+ +

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,来源于 JavaScript 同时也被多种语言所使用。 JSON 用于构建通用的数据结构。参见 {{Glossary("JSON")}} 以及 {{jsxref("JSON")}} 了解更多。

+ +

标准库中更多的对象

+ +

JavaScript 有一个内置对象的标准库。请查看参考来了解更多对象。

+ +

使用 typeof 操作符判断对象类型

+ +

typeof 运算符可以帮助你查询变量的类型。要了解更多细节和注意事项请阅读参考页

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ES1')}}{{Spec2('ES1')}}初始定义
{{SpecName('ES5.1', '#sec-8', 'Types')}}{{Spec2('ES5.1')}}
{{SpecName('ES2015', '#sec-ecmascript-data-types-and-values', 'ECMAScript Data Types and Values')}}{{Spec2('ES2015')}} +

Added Symbol.

+
{{SpecName('ESDraft', '#sec-ecmascript-data-types-and-values', 'ECMAScript Data Types and Values')}}{{Spec2('ESDraft')}}
+ +

参考资料

+ + diff --git a/files/zh-cn/web/javascript/ecmascript_7_support_in_mozilla/index.html b/files/zh-cn/web/javascript/ecmascript_7_support_in_mozilla/index.html new file mode 100644 index 0000000000..55732f87ad --- /dev/null +++ b/files/zh-cn/web/javascript/ecmascript_7_support_in_mozilla/index.html @@ -0,0 +1,82 @@ +--- +title: Mozilla对下一代ECMAScript 的支持 +slug: Web/JavaScript/ECMAScript_7_support_in_Mozilla +tags: + - ECMAScript 2015 + - ECMAScript 2016 + - ECMAScript 2017 + - ECMAScript 2018 + - new features +translation_of: Archive/Web/JavaScript/ECMAScript_Next_support_in_Mozilla +--- +
{{jsSidebar("New_in_JS")}}
+ +

下一代 ECMAScript 是指在 ECMAScript 2015 被推出后的 ECMA-262 标准(通常被称为 JavaScript)的新特性。新版本的 ECMAScript 规范会每年发布。

+ +

你可以在 tc39/ecma262 这个仓库中看见当前的规范草案。

+ +

es-discuss 是一个关于 ECMAScript 标准有关反馈的渠道。

+ +

ECMAScript 2016

+ +

下面的 ECMAScript 2016 特性已实现:

+ +

 

+ + + +

ECMAScript 2017

+ +

下面的 ECMAScript 2017 特性已实现:

+ +

 

+ + + +

实验性的新特性

+ +

以下特性已经实现,但可能仅在 Firefox Nightly 中可用、或者需要浏览器 flags 开启;且此提案的标准可能尚未正式进入 ECMAScript 规范,请小心使用。

+ +

ArrayBuffer 对象的新方法

+ + + +

新的 TypedObject 对象

+ + + +

新的 Shared Memory 对象

+ + + +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/enumerability_and_ownership_of_properties/index.html b/files/zh-cn/web/javascript/enumerability_and_ownership_of_properties/index.html new file mode 100644 index 0000000000..47f75f244a --- /dev/null +++ b/files/zh-cn/web/javascript/enumerability_and_ownership_of_properties/index.html @@ -0,0 +1,309 @@ +--- +title: 属性的可枚举性和所有权 +slug: Web/JavaScript/Enumerability_and_ownership_of_properties +tags: + - JavaScript + - 对象 + - 属性 +translation_of: Web/JavaScript/Enumerability_and_ownership_of_properties +--- +
{{JsSidebar("More")}}
+ +

可枚举属性是指那些内部 “可枚举” 标志设置为 true 的属性,对于通过直接的赋值和属性初始化的属性,该标识值默认为即为 true,对于通过 Object.defineProperty 等定义的属性,该标识值默认为 false。可枚举的属性可以通过 for...in 循环进行遍历(除非该属性名是一个 Symbol)。属性的所有权是通过判断该属性是否直接属于某个对象决定的,而不是通过原型链继承的。一个对象的所有的属性可以一次性的获取到。有一些内置的方法可以用于判断、迭代/枚举以及获取对象的一个或一组属性,下表对这些方法进行了列举。对于部分不可用的类别,下方的示例代码对获取方法进行了演示。

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性的可枚举性和所有权 - 内置的判断、访问和迭代方法
作用自身对象自身对象及其原型链仅原型链
判断 + + + + + + + + + + + + + + + +
可枚举属性不可枚举属性可枚举属性及不可枚举属性
propertyIsEnumerable
+ hasOwnProperty
hasOwnProperty 获取属性后使用 propertyIsEnumerable 过滤可枚举属性hasOwnProperty
+
+ + + + + + + + + + + + + + + +
可枚举属性不可枚举属性可枚举属性及不可枚举属性
需要额外代码实现需要额外代码实现in
+
需要额外代码实现
访问 + + + + + + + + + + + + + + + +
可枚举属性不可枚举属性可枚举属性及不可枚举属性
Object.keys
+ getOwnPropertyNames
+ getOwnPropertySymbols
getOwnPropertyNamesgetOwnPropertySymbols 获取属性后使用 propertyIsEnumerable 过滤可枚举属性getOwnPropertyNames
+ getOwnPropertySymbols
+
需要额外代码实现需要额外代码实现
迭代 + + + + + + + + + + + + + + + +
可枚举属性不可枚举属性可枚举属性及不可枚举属性
Object.keys
+ getOwnPropertyNames
+ getOwnPropertySymbols
getOwnPropertyNamesgetOwnPropertySymbols 获取属性后使用 propertyIsEnumerable 过滤可枚举属性getOwnPropertyNames
+ getOwnPropertySymbols
+
+ + + + + + + + + + + + + + + +
可枚举属性不可枚举属性可枚举属性及不可枚举属性
for..in
+ (同时会排除 Symbol)
需要额外代码实现需要额外代码实现
+
需要额外代码实现
+
+ +

通过可枚举性和所有权获取对象的属性

+ +

注:以下实现并非使用于所有情况的最优算法,但可以快捷的展示语言特性。

+ + + +
var SimplePropertyRetriever = {
+    getOwnEnumerables: function(obj) {
+        return this._getPropertyNames(obj, true, false, this._enumerable);
+         // Or could use for..in filtered with hasOwnProperty or just this: return Object.keys(obj);
+    },
+    getOwnNonenumerables: function(obj) {
+        return this._getPropertyNames(obj, true, false, this._notEnumerable);
+    },
+    getOwnEnumerablesAndNonenumerables: function(obj) {
+        return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable);
+        // Or just use: return Object.getOwnPropertyNames(obj);
+    },
+    getPrototypeEnumerables: function(obj) {
+        return this._getPropertyNames(obj, false, true, this._enumerable);
+    },
+    getPrototypeNonenumerables: function(obj) {
+        return this._getPropertyNames(obj, false, true, this._notEnumerable);
+    },
+    getPrototypeEnumerablesAndNonenumerables: function(obj) {
+        return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable);
+    },
+    getOwnAndPrototypeEnumerables: function(obj) {
+        return this._getPropertyNames(obj, true, true, this._enumerable);
+        // Or could use unfiltered for..in
+    },
+    getOwnAndPrototypeNonenumerables: function(obj) {
+        return this._getPropertyNames(obj, true, true, this._notEnumerable);
+    },
+    getOwnAndPrototypeEnumerablesAndNonenumerables: function(obj) {
+        return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable);
+    },
+    // Private static property checker callbacks
+    _enumerable: function(obj, prop) {
+        return obj.propertyIsEnumerable(prop);
+    },
+    _notEnumerable: function(obj, prop) {
+        return !obj.propertyIsEnumerable(prop);
+    },
+    _enumerableAndNotEnumerable: function(obj, prop) {
+        return true;
+    },
+    // Inspired by http://stackoverflow.com/a/8024294/271577
+    _getPropertyNames: function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) {
+        var props = [];
+
+        do {
+            if (iterateSelfBool) {
+                Object.getOwnPropertyNames(obj).forEach(function(prop) {
+                    if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) {
+                        props.push(prop);
+                    }
+                });
+            }
+            if (!iteratePrototypeBool) {
+                break;
+            }
+            iterateSelfBool = true;
+        } while (obj = Object.getPrototypeOf(obj));
+
+        return props;
+    }
+};
+ +

统计表

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
infor..inobj.hasOwnPropertyobj.propertyIsEnumerableObject.keysObject.getOwnPropertyNamesObject.getOwnPropertyDescriptorsReflect.ownKeys()
自身的可枚举属性truetruetruetruetruetruetruetrue
自身的不可枚举属性truefalsetruefalsefalsetruetruetrue
自身的Symbol 键truefalsetruetruefalsefalsetruetrue
继承的可枚举属性truetruefalsefalsefalsefalsefalsefalse
继承的不可枚举属性truefalsefalsefalsefalsefalsefalsefalse
继承的 Symbol 键truefalsefalsefalsefalsefalsefalsefalse
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/equality_comparisons_and_sameness/index.html b/files/zh-cn/web/javascript/equality_comparisons_and_sameness/index.html new file mode 100644 index 0000000000..6ef100b114 --- /dev/null +++ b/files/zh-cn/web/javascript/equality_comparisons_and_sameness/index.html @@ -0,0 +1,436 @@ +--- +title: JavaScript 中的相等性判断 +slug: Web/JavaScript/Equality_comparisons_and_sameness +tags: + - JavaScr + - 严格相等 + - 同值相等 + - 比较 + - 相等 + - 零值相等 + - 非严格相等 +translation_of: Web/JavaScript/Equality_comparisons_and_sameness +--- +
{{jsSidebar("Intermediate")}}
+ +

ES2015中有四种相等算法:

+ + + +

JavaScript提供三种不同的值比较操作:

+ + + +

选择使用哪个操作取决于你需要什么样的比较。

+ +

简而言之,在比较两件事情时,双等号将执行类型转换; 三等号将进行相同的比较,而不进行类型转换 (如果类型不同, 只是总会返回 false );  而Object.is的行为方式与三等号相同,但是对于NaN和-0和+0进行特殊处理,所以最后两个不相同,而Object.is(NaN,NaN)将为 true。(通常使用双等号或三等号将NaN与NaN进行比较,结果为false,因为IEEE 754如是说.) 请注意,所有这些之间的区别都与其处理原语有关; 这三个运算符的原语中,没有一个会比较两个变量是否结构上概念类似。对于任意两个不同的非原始对象,即便他们有相同的结构, 以上三个运算符都会计算得到 false 。

+ +

严格相等 ===

+ +

全等操作符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换。如果两个被比较的值具有不同的类型,这两个值是不全等的。否则,如果两个被比较的值类型相同,值也相同,并且都不是 number 类型时,两个值全等。最后,如果两个值都是 number 类型,当两个都不是 NaN,并且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的。

+ +
var num = 0;
+var obj = new String("0");
+var str = "0";
+var b = false;
+
+console.log(num === num); // true
+console.log(obj === obj); // true
+console.log(str === str); // true
+
+console.log(num === obj); // false
+console.log(num === str); // false
+console.log(obj === str); // false
+console.log(null === undefined); // false
+console.log(obj === null); // false
+console.log(obj === undefined); // false
+
+ +

在日常中使用全等操作符几乎总是正确的选择。对于除了数值之外的值,全等操作符使用明确的语义进行比较:一个值只与自身全等。对于数值,全等操作符使用略加修改的语义来处理两个特殊情况:第一个情况是,浮点数 0 是不分正负的。区分 +0 和 -0 在解决一些特定的数学问题时是必要的,但是大部分情况下我们并不用关心。全等操作符认为这两个值是全等的。第二个情况是,浮点数包含了 NaN 值,用来表示某些定义不明确的数学问题的解,例如:正无穷加负无穷。全等操作符认为 NaN 与其他任何值都不全等,包括它自己。(等式 (x !== x) 成立的唯一情况是 x 的值为 NaN)

+ +

非严格相等 ==

+ +

相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。在转换后(等式的一边或两边都可能被转换),最终的比较方式等同于全等操作符 === 的比较方式。 相等操作符满足交换律。

+ +

相等操作符对于不同类型的值,进行的比较如下图所示:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
被比较值 B
UndefinedNullNumberStringBooleanObject
被比较值 AUndefinedtruetruefalsefalsefalseIsFalsy(B)
NulltruetruefalsefalsefalseIsFalsy(B)
NumberfalsefalseA === BA === ToNumber(B)A=== ToNumber(B) A== ToPrimitive(B)
StringfalsefalseToNumber(A) === BA === BToNumber(A) === ToNumber(B)ToPrimitive(B) == A
BooleanfalsefalseToNumber(A) === BToNumber(A) === ToNumber(B)A === BToNumber(A) == ToPrimitive(B)
ObjectfalsefalseToPrimitive(A) == BToPrimitive(A) == BToPrimitive(A) == ToNumber(B) +

A === B

+
+ +

在上面的表格中,ToNumber(A) 尝试在比较前将参数 A 转换为数字,这与 +A(单目运算符+)的效果相同。ToPrimitive(A)通过尝试调用 A 的A.toString() 和 A.valueOf() 方法,将参数 A 转换为原始值(Primitive)。

+ +

一般而言,根据 ECMAScript 规范,所有的对象都与 undefined null 不相等。但是大部分浏览器允许非常窄的一类对象(即,所有页面中的 document.all 对象),在某些情况下,充当效仿 undefined 的角色。相等操作符就是在这样的一个背景下。因此,IsFalsy(A) 方法的值为 true ,当且仅当 A 效仿 undefined。在其他所有情况下,一个对象都不会等于 undefined null

+ +
var num = 0;
+var obj = new String("0");
+var str = "0";
+var b = false;
+
+console.log(num == num); // true
+console.log(obj == obj); // true
+console.log(str == str); // true
+
+console.log(num == obj); // true
+console.log(num == str); // true
+console.log(obj == str); // true
+console.log(null == undefined); // true
+
+// both false, except in rare cases
+console.log(obj == null);
+console.log(obj == undefined);
+
+ +

有些开发者认为,最好永远都不要使用相等操作符。全等操作符的结果更容易预测,并且因为没有隐式转换,全等比较的操作会更快。

+ +

同值相等

+ +

同值相等解决了最后一个用例确定两个值是否在任何情况下功能上是相同的。(这个用例演示了里氏替换原则的实例。)当试图对不可变(immutable)属性修改时发生出现的情况:

+ +
// 向 Nmuber 构造函数添加一个不可变的属性 NEGATIVE_ZERO
+Object.defineProperty(Number, "NEGATIVE_ZERO",
+                      { value: -0, writable: false, configurable: false, enumerable: false });
+
+function attemptMutation(v)
+{
+  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
+}
+
+ +

Object.defineProperty 在试图修改不可变属性时,如果这个属性确实被修改了则会抛出异常,反之什么都不会发生。例如如果 v 是 -0 ,那么没有发生任何变化,所以也不会抛出任何异常。但如果 v 是 +0 ,则会抛出异常。不可变属性和新设定的值使用 same-value 相等比较。

+ +

同值相等由 Object.is 方法提供。

+ +

零值相等

+ +

与同值相等类似,不过会认为 +0 与 -0 相等。

+ +

规范中的相等、严格相等以及同值相等

+ +

在 ES5 中, == 相等在 Section 11.9.3, The Abstract Equality Algorithm=== 相等在 11.9.6, The Strict Equality Algorithm。(请参考这两个链接,他们很简洁易懂。提示:请先阅读严格相等的算法)ES5 也提供了 same-value 相等, Section 9.12, The SameValue Algorithm ,用在 JS 引擎内部。除了 11.9.6.4 和 9.12.4 在处理数字上的不同外,它基本和严格相等算法相同。ES6 简单地通过  Object.is 暴露了这个算法。

+ +

我们可以看到,使用双等或三等时,除了 11.9.6.1 类型检查,严格相等算法是相等算法的子集因为 11.9.6.2–7 对应 11.9.3.1.a–f。

+ +

理解相等比较的模型

+ +

在 ES2015 以前,你可能会说双等和三等是“扩展”的关系。比如有人会说双等是三等的扩展版,因为他处理三等所做的,还做了类型转换。例如 6 == "6" 。反之另一些人可能会说三等是双等的扩展,因为他还要求两个参数的类型相同,所以增加了更多的限制。怎样理解取决于你怎样看待这个问题。

+ +

但是这种比较的方式没办法把 ES2015 的 Object.is 排列到其中。因为 Object.is 并不比双等更宽松,也并不比三等更严格,当然也不是在他们中间。从下表中可以看出,这是由于 Object.is 处理 NaN 的不同。注意假如 Object.is(NaN, NaN) 被计算成 false ,我们就可以说他比三等更为严格,因为他可以区分 -0+0 。但是对 NaN 的处理表明,这是不对的。 Object.is 应该被认为是有其特殊的用途,而不应说他和其他的相等更宽松或严格。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
判等
xy=====Object.is
undefinedundefinedtruetruetrue
nullnulltruetruetrue
truetruetruetruetrue
falsefalsetruetruetrue
"foo""foo"truetruetrue
00truetruetrue
+0-0truetruefalse
0falsetruefalsefalse
""falsetruefalsefalse
""0truefalsefalse
"0"0truefalsefalse
"17"17truefalsefalse
[1,2]"1,2"truefalsefalse
new String("foo")"foo"truefalsefalse
nullundefinedtruefalsefalse
nullfalsefalsefalsefalse
undefinedfalsefalsefalsefalse
{ foo: "bar" }{ foo: "bar" }falsefalsefalse
new String("foo")new String("foo")falsefalsefalse
0nullfalsefalsefalse
0NaNfalsefalsefalse
"foo"NaNfalsefalsefalse
NaNNaNfalsefalsetrue
+ +

什么时候使用 Object.is 或是三等

+ +

总的来说,除了对待NaN的方式,Object.is唯一让人感兴趣的,是当你需要一些元编程方案时,它对待0的特殊方式,特别是关于属性描述器,即你的工作需要去镜像Object.defineProperty的一些特性时。如果你的工作不需要这些,那你应该避免使用Object.is,使用===来代替。即使你需要比较两个NaN使其结果为true,总的来说编写使用NaN 检查的特例函数(用旧版本ECMAScript的isNaN方法)也会比想出一些计算方法让Object.is不影响不同符号的0的比较更容易些。

+ +

这里是一个会区别对待-0和+0的内置方法和操作符不完全列表:

+ +

- (一元负)

+ +
+
+

显而易见,对0一元负操作得到-0。但表达式的抽象化可能在你没有意识到得情况下导致-0延续传播。例如当考虑下例时:

+ +
let stoppingForce = obj.mass * -obj.velocity
+ +
+ +

如果obj.velocity0 (或计算结果为0), 一个-0就在上处产生并被赋值为stoppingForce的值.

+
+
+ +
+
Math.atan2
+
Math.ceil
+
Math.pow
+
Math.round
+
+ +
+
即使传入的参数中没有-0,这些方法的返回值都有可能是-0。例如当用 Math.pow计算-Infinity的任何负奇指数的幂都会得到-0。详情请参见这些方法各自的文档。
+
+ +
+
Math.floor
+
Math.max
+
Math.min
+
Math.sin
+
Math.sqrt
+
Math.tan
+
+ +
+
当传入参数中有-0时,这些方法也可能返回-0。例如, Math.min(-0, +0) 得出 -0。详情请参见这些方法各自的文档。
+
+ +
+
~
+
<<
+
>>
+
这些操作符内部都使用了ToInt32算法。因为内部32位整数类型只有一个0(没有符号区别),-0的符号在反操作后并不会保留下来。例如Object.is(~~(-0), -0)Object.is(-0 << 2 >> 2, -0) 都会得到false.
+
+ +

在未考虑0的符号的情况下依赖于Object.is是危险的。当然,如果本意就是区分-0和+0的话,Object.is能按照期望完成工作。

+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/eventloop/index.html b/files/zh-cn/web/javascript/eventloop/index.html new file mode 100644 index 0000000000..3decb3824e --- /dev/null +++ b/files/zh-cn/web/javascript/eventloop/index.html @@ -0,0 +1,159 @@ +--- +title: 并发模型与事件循环 +slug: Web/JavaScript/EventLoop +tags: + - JavaScript + - 事件 + - 事件处理 + - 事件循环 + - 事件管理 + - 事件队列 + - 进阶 +translation_of: Web/JavaScript/EventLoop +--- +
{{JsSidebar("Advanced")}}
+ +

JavaScript有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。这个模型与其它语言中的模型截然不同,比如 C 和 Java。

+ +

运行时概念

+ +

接下来的内容解释了这个理论模型。现代JavaScript引擎实现并着重优化了以下描述的这些语义。

+ +

可视化描述

+ +

Stack, heap, queue

+ +

+ +

函数调用形成了一个由若干帧组成的栈。

+ +
function foo(b) {
+  let a = 10;
+  return a + b + 11;
+}
+
+function bar(x) {
+  let y = 3;
+  return foo(x * y);
+}
+
+console.log(bar(7)); // 返回 42
+ +

当调用 bar 时,第一个帧被创建并压入栈中,帧中包含了 bar 的参数和局部变量。 当 bar 调用 foo 时,第二个帧被创建并被压入栈中,放在第一个帧之上,帧中包含 foo 的参数和局部变量。当 foo 执行完毕然后返回时,第二个帧就被弹出栈(剩下 bar 函数的调用帧 )。当 bar 也执行完毕然后返回时,第一个帧也被弹出,栈就被清空了。

+ +

+ +

对象被分配在堆中,堆是一个用来表示一大块(通常是非结构化的)内存区域的计算机术语。

+ +

队列

+ +

一个 JavaScript 运行时包含了一个待处理消息的消息队列。每一个消息都关联着一个用以处理这个消息的回调函数。

+ +

事件循环 期间的某个时刻,运行时会从最先进入队列的消息开始处理队列中的消息。被处理的消息会被移出队列,并作为输入参数来调用与之关联的函数。正如前面所提到的,调用一个函数总是会为其创造一个新的栈帧。

+ +

函数的处理会一直进行到执行栈再次为空为止;然后事件循环将会处理队列中的下一个消息(如果还有的话)。

+ +

事件循环

+ +

之所以称之为 事件循环,是因为它经常按照类似如下的方式来被实现:

+ +
while (queue.waitForMessage()) {
+  queue.processNextMessage();
+}
+ +

queue.waitForMessage() 会同步地等待消息到达(如果当前没有任何消息等待被处理)。

+ +

"执行至完成"

+ +

每一个消息完整地执行后,其它消息才会被执行。这为程序的分析提供了一些优秀的特性,包括:当一个函数执行时,它不会被抢占,只有在它运行完毕之后才会去运行任何其他的代码,才能修改这个函数操作的数据。这与C语言不同,例如,如果函数在线程中运行,它可能在任何位置被终止,然后在另一个线程中运行其他代码。

+ +

这个模型的一个缺点在于当一个消息需要太长时间才能处理完毕时,Web应用程序就无法处理与用户的交互,例如点击或滚动。为了缓解这个问题,浏览器一般会弹出一个“这个脚本运行时间过长”的对话框。一个良好的习惯是缩短单个消息处理时间,并在可能的情况下将一个消息裁剪成多个消息。

+ +

添加消息

+ +

在浏览器里,每当一个事件发生并且有一个事件监听器绑定在该事件上时,一个消息就会被添加进消息队列。如果没有事件监听器,这个事件将会丢失。所以当一个带有点击事件处理器的元素被点击时,就会像其他事件一样产生一个类似的消息。

+ +

函数 setTimeout 接受两个参数:待加入队列的消息和一个时间值(可选,默认为 0)。这个时间值代表了消息被实际加入到队列的最小延迟时间。如果队列中没有其它消息并且栈为空,在这段延迟时间过去之后,消息会被马上处理。但是,如果有其它消息,setTimeout 消息必须等待其它消息处理完。因此第二个参数仅仅表示最少延迟时间,而非确切的等待时间。

+ +

下面的例子演示了这个概念(setTimeout 并不会在计时器到期之后直接执行):

+ +
const s = new Date().getSeconds();
+
+setTimeout(function() {
+  // 输出 "2",表示回调函数并没有在 500 毫秒之后立即执行
+  console.log("Ran after " + (new Date().getSeconds() - s) + " seconds");
+}, 500);
+
+while(true) {
+  if(new Date().getSeconds() - s >= 2) {
+    console.log("Good, looped for 2 seconds");
+    break;
+  }
+}
+ +

零延迟

+ +

零延迟并不意味着回调会立即执行。以 0 为第二参数调用 setTimeout 并不表示在 0 毫秒后就立即调用回调函数。

+ +

其等待的时间取决于队列里待处理的消息数量。在下面的例子中,"这是一条消息" 将会在回调获得处理之前输出到控制台,这是因为延迟参数是运行时处理请求所需的最小等待时间,但并不保证是准确的等待时间。

+ +

基本上,setTimeout 需要等待当前队列中所有的消息都处理完毕之后才能执行,即使已经超出了由第二参数所指定的时间。

+ +
(function() {
+
+  console.log('这是开始');
+
+  setTimeout(function cb() {
+    console.log('这是来自第一个回调的消息');
+  });
+
+  console.log('这是一条消息');
+
+  setTimeout(function cb1() {
+    console.log('这是来自第二个回调的消息');
+  }, 0);
+
+  console.log('这是结束');
+
+})();
+
+// "这是开始"
+// "这是一条消息"
+// "这是结束"
+// "这是来自第一个回调的消息"
+// "这是来自第二个回调的消息"
+
+ +

多个运行时互相通信

+ +

一个 web worker 或者一个跨域的 iframe 都有自己的栈、堆和消息队列。两个不同的运行时只能通过 postMessage 方法进行通信。如果另一个运行时侦听 message 事件,则此方法会向该运行时添加消息。

+ +

永不阻塞

+ +

JavaScript的事件循环模型与许多其他语言不同的一个非常有趣的特性是,它永不阻塞。 处理 I/O 通常通过事件和回调来执行,所以当一个应用正等待一个 IndexedDB 查询返回或者一个 XHR 请求返回时,它仍然可以处理其它事情,比如用户输入。

+ +

由于历史原因有一些例外,如 alert 或者同步 XHR,但应该尽量避免使用它们。注意,例外的例外也是存在的(但通常是实现错误而非其它原因)。

+ +

标准规范

+ + + + + + + + + + + + + + + + + + + + + +
标准规范状态注释
{{SpecName('HTML WHATWG', 'webappapis.html#event-loops', 'Event loops')}}{{Spec2('HTML WHATWG')}}
Node.js 事件循环Living Standard
diff --git a/files/zh-cn/web/javascript/getting_started/index.html b/files/zh-cn/web/javascript/getting_started/index.html new file mode 100644 index 0000000000..9ffa849809 --- /dev/null +++ b/files/zh-cn/web/javascript/getting_started/index.html @@ -0,0 +1,293 @@ +--- +title: 起步(Javascript 教程) +slug: Web/JavaScript/Getting_Started +tags: + - bug-840092 +translation_of: Learn/Getting_started_with_the_web/JavaScript_basics +--- +

JavaScript是什么?

+ +

作为一门计算机语言,JavaScript本身强大、复杂,且难于理解。但是,你可以用它来开发一系列的应用程序,它有巨大的潜力来改变当前的互联网现状。下面这个应用程序就是一个很好的例子:Google Maps

+ +

JavaScript(通称为ECMAScript)最大的优势在于,它基于浏览器,但是通过浏览器的支持可以在不同平台上生产出相同结果。 本文举出的例子是 Google Maps,它几乎可以无差别的运行在 Linux、Windows和Mac OS系统中。 伴随大量JavaScript类库的出现,你现在可以用它很轻易的实现文档导航、DOM元素选择、创建动画、处理事件和开发AJAX应用。同其他因各种利益目的而推动的技术不同,JavaScript是一种真正免费并且被广泛采用的跨平台编程语言。

+ +

你应该知道

+ +

JavaScript是一种非常容易入门的编程语言。你只需要一个文本编辑器和web浏览器就可以开始进行学习。 

+ +

在使用 JavaScript进行开发的过程中,可能还会涉及很多其他技术,这不在本文讨论的范围之内。 所以,不要期望在学习的第一天就能开发出一个类似 Google maps 这样的应用程序。

+ +

起步

+ +

JavaScript的起步非常简单。你不需要进行复杂的程序安装,不需要去了解如何使用shell、打包器或编译器。它是通过浏览器来展示的,你所需要做的全部事情就是把你的代码保存为文本文件,然后再浏览器中打开。就这么简单!

+ +

JavaScript非常适合作为入门级的编程语言。它直观形象,并且教会学生认识到这是一个在实际生活中非常有用的工具。 对比C、C++和 Java等语言会发现有很大不同,它们只对那些专业的软件开发者来说是有价值的。

+ +

浏览器兼容问题

+ +

不同浏览器在功能实现上有很多不同之处。Mozilla, Microsoft IE, Apple Safari 和 Opera 在行为上有很多差异。 我们计划在此记录这些差异 documenting these variations。你可以使用各种跨平台的JavaScript API接口来解决这些兼容性问题。这些API隐藏了浏览器之间的各种差异,提供了通用性的功能函数来方便调用。

+ +

如何运行示例

+ +

下面的例子都有相同的代码。要执行它们有多种方法,如果你有自己的个人站点,你还可以在站点上把这些例子保存为新的页面。

+ +

如果你没有自己的个人站点,你可以在电脑上把这些例子保存下来,并使用你自己的浏览器来执行它们。这就是JavaScript简单的地方,也是它适合做入门语言的原因。你不需要编译器或者开发环境,你只需要一个浏览器就可以开始起步了。

+ +

举例:捕获一个鼠标单击事件

+ +

事件处理 (事件类型、事件注册、冒泡等) 的细节是一个非常宽泛的话题,这个简单的例子并不能说明所有的问题。然而,如果我们不涉及JavaScript事件系统,我们就不能很好展示一个鼠标点击捕获的范例。你只需要记得例子里展示的只是JavaScrpt事件系统里非常表象的一些东西,如果你想要了解更多的内部细节,那你可以去查找更详细的相关资料。

+ +

鼠标事件只是浏览器同用户交互过程中所产生的事件系统里的一个子集。下面列举了一些用户在交互过程中产生的具体的鼠标事件:

+ + + +

捕获事件并注册处理函数最简单的办法就是使用HTML,你可以把事件当成元素属性来使用。例子:

+ +
  <span onclick="alert('Hello World!');">Click Here</span>
+ +

要执行的JavaScript代码既可以作为属性值写在行内位置,也可以写成函数并用<script>包裹后放到HTML页面中:

+ +
<script type="text/javascript">
+  function onclick_callback () {
+     alert ("Hello, World!");
+  }
+</script>
+<span onclick="onclick_callback();">Click Here</span>
+ +

另外,事件对象是可以被捕获和引用,开发者可以通过访问事件对象来获取更多信息,如捕获事件的对象、事件类型、哪个鼠标按键被点击等。我们还用上面的例子来说明:

+ +
<script type="text/javascript">
+  function onclick_callback(event) {
+    var eType = event.type;
+    /* the following is for compatability */
+    /* Moz populates the target property of the event object */
+    /* IE populates the srcElement property */
+    var eTarget = event.target || event.srcElement;
+
+    alert( "Captured Event (type=" + eType + ", target=" + eTarget );
+  }
+</script>
+<span onclick="onclick_callback(event);">Click Here</span>
+ +

对于事件的注册和接收还用注意一些的是,你可以给任何使用JavaScript生成的HTMLElement对象做相同的操作。下面的例子展示了一个这样的过程:生成span对象,添加到页面中的body,给span注册mouse-over、mouse-out、mouse-down和 mouse-up事件。

+ +
<script type="text/javascript">
+  function mouseevent_callback(event) {
+    /* The following is for compatability */
+    /* IE does NOT by default pass the event object */
+    /* obtain a ref to the event if one was not given */
+    if (!event) event = window.event;
+
+    /* obtain event type and target as earlier */
+    var eType = event.type;
+    var eTarget = event.target || event.srcElement;
+    alert(eType +' event on element with id: '+ eTarget.id);
+  }
+
+ function onload () {
+   /* obtain a ref to the 'body' element of the page */
+   var body = document.body;
+   /* create a span element to be clicked */
+   var span = document.createElement('span');
+   span.id = 'ExampleSpan';
+   span.appendChild(document.createTextNode ('Click Here!'));
+
+   /* register the span object to receive specific mouse events */
+   span.onmousedown = mouseevent_callback;
+   span.onmouseup = mouseevent_callback;
+   span.onmouseover = mouseevent_callback;
+   span.onmouseout = mouseevent_callback;
+
+   /* display the span on the page */
+   body.appendChild(span);
+}
+</script>
+ +

{{ draft() }}

+ +

举例:捕获一个键盘事件

+ +

同上面的例子类似,键盘事件捕获也依赖于JavaScript事件系统。当键盘上的键被使用的时候触发键盘事件。

+ +

下面的列表展示了一些具体的键盘事件,同鼠标事件相比是很少的:

+ + + +

在一个 keypress 事件中,键值的Unicode编码会存储到属性keyCode或者charCode 中,但是两者不会同时存在。按键会生成一个字母 (如 'a'),这时会把字母的编码存储到charCode 中,注意这里是区分大小写的( charCode 会判断shift键是否同时被按下)。其他情况下,编码会存储到 keyCode中。

+ +

捕获键盘事件最简单的方法仍然是在HTML中注册键盘事件的处理函数,在元素属性中处理相关事件。 举例:

+ +
  <input type="text" onkeypress="alert ('Hello World!');"></input>
+
+ +

同鼠标事件类似,你的 JavaScript代码既可以写到属性值内,也可以作为函数用<script包裹后写到HTML页面中:

+ +
<script type="text/javascript">
+  function onkeypress_callback () {
+    alert ("Hello, World!");
+  }
+</script>
+
+<input onkeypress="onkeypress_callback();"></input>
+
+ +

捕获事件和引用事件源(一个真实的键被按下时) 的方法同鼠标事件类似:

+ +
<script type="text/javascript">
+  function onkeypress_callback(evt) {
+      var eType = evt.type; // Will return "keypress" as the event type
+      var eCode = 'keyCode is ' + evt.keyCode;
+      var eChar = 'charCode is ' + evt.charCode;
+
+      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
+   }
+</script>
+<input onkeypress="onkeypress_callback(event);"></input>
+ +

要捕获页面上所有的键盘事件,可以在document上注册和绑定相关的处理函数:

+ +
<script type="text/javascript">
+  document.onkeypress = key_event;
+  document.onkeydown = key_event;
+  document.onkeyup = key_event;
+
+  function key_event(evt) {
+      var eType = evt.type;
+      var eCode = "ASCII code is " + evt.keyCode;
+      var eChar = 'charCode is ' + evt.charCode;
+
+      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
+   }
+</script>
+ +

下面是一个完整的键盘事件处理过程:

+ +
<!DOCTYPE html>
+<html>
+<head>
+  <script>
+    var metaChar = false;
+    var exampleKey = 16;
+    function keyEvent(event) {
+      var key = event.keyCode || event.which;
+      var keychar = String.fromCharCode(key);
+      if (key==exampleKey) { metaChar = true; }
+      if (key!=exampleKey) {
+         if (metaChar) {
+            alert("Combination of metaKey + " + keychar)
+            metaChar = false;
+         } else { alert("Key pressed " + key); }
+      }
+    }
+    function metaKeyUp (event) {
+      var key = event.keyCode || event.which;
+      if (key==exampleKey) { metaChar = false; }
+    }
+  </script>
+</head>
+<body onkeydown="keyEvent(event)" onkeyup="metaKeyUp(event)">
+</body>
+</html>
+ +

浏览器 bugs 和 quirks

+ +

键盘事件中有两个可用的属性keyCode 和 charCode。通常情况下,keyCode 指向的是用户按下的键盘上的那个键,而charCode 存储的是相应键的 ASCII 码值。这两个值不一定相同,如, 小写 'a' 和 大写 'A' 拥有相同的 keyCode,因为用户按下的是相同的按键,但是他们的charCode不同,因为两个字母的码值不同。 

+ +

不同浏览器对于charCode的处理方式并不统一。例如Internet Explorer 和Opera 并不支持 charCode,他们把字母信息写到了keyCode中,而且只在 onkeypress下有效。在 Onkeydown 和Onkeyup的事件中, keyCode 存储的仍然是按键的相关信息。 Firefox 则使用 "which", 来区分字母。.

+ +

可以到 Mozilla 文档 Keyboard Events 去了解关于键盘事件的更多信息。.

+ +

{{ draft() }}

+ +

举例:拖曳图片

+ +

下面的例子展示了firefox浏览器下如何实现拖动图片:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<style type='text/css'>
+img { position: absolute; }
+</style>
+
+<script type='text/javascript'>
+window.onload = function() {
+
+  movMeId=document.getElementById("ImgMov");
+  movMeId.style.top = "80px";
+  movMeId.style.left = "80px";
+  movMeId.style.position = "absolute";
+
+  document.onmousedown = coordinates;
+  document.onmouseup=mouseup;
+
+  function coordinates(e) {
+    if (e == null) { e = window.event;}
+    var sender = (typeof( window.event ) != "undefined" ) ? e.srcElement : e.target;
+
+    if (sender.id=="ImgMov") {
+      mouseover = true;
+      pleft = parseInt(movMeId.style.left);
+      ptop = parseInt(movMeId.style.top);
+      xcoor = e.clientX;
+      ycoor = e.clientY;
+      document.onmousemove=moveImage;
+      return false;
+    } else {
+        return false;
+    }
+  }
+
+  function moveImage(e) {
+    if (e == null) { e = window.event; }
+    movMeId.style.left = pleft+e.clientX-xcoor+"px";
+    movMeId.style.top = ptop+e.clientY-ycoor+"px";
+    return false;
+  }
+
+  function mouseup(e) {
+    document.onmousemove = null;
+  }
+}
+</script>
+</head>
+
+<body>
+  <img id="ImgMov" src="http://mozcom-cdn.mozilla.net/img/covehead/about/logo/download/logo-only.png" width="64" height="64"/>
+  <p>Drag and drop around the image in this page.</p>
+</body>
+
+</html>
+ +

举例:改变大小

+ +
{{todo("Need Content. Or, remove headline")}}
+ +

举例:绘制直线

+ +
+

附加文档信息

+ + +
+ +

 

diff --git a/files/zh-cn/web/javascript/guide/about/index.html b/files/zh-cn/web/javascript/guide/about/index.html new file mode 100644 index 0000000000..115939595c --- /dev/null +++ b/files/zh-cn/web/javascript/guide/about/index.html @@ -0,0 +1,135 @@ +--- +title: 关于本指南 +slug: Web/JavaScript/Guide/About +tags: + - JavaScript + - 初学者 + - 指南 +translation_of: Web/JavaScript/Guide/Introduction +--- +

JavaScript 是一种跨平台的,基于对象的脚本语言。本指南介绍了所有您使用 JavaScript 所需要了解的事情。

+ +

JavaScript 各版本中的新特性

+ + +

+ +

您应该已经了解的事情

+ +

本指南假设您具有以下背景:

+ + + +

JavaScript 版本

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
表格 1 JavaScript 和 Navigator 版本对照
JavaScript 版本Navigator 版本
JavaScript 1.0Navigator 2.0
JavaScript 1.1Navigator 3.0
JavaScript 1.2Navigator 4.0-4.05
JavaScript 1.3Navigator 4.06-4.7x
JavaScript 1.4 
JavaScript 1.5Navigator 6.0
+ Mozilla (开源浏览器)
JavaScript 1.6Firefox 1.5,及其它基于 Mozilla 1.8 的产品
JavaScript 1.7Firefox 2,及其它基于 Mozilla 1.8.1 的产品
JavaScript 1.8Firefox 3,及其它基于 Gecko 1.9 的产品
+ +

哪里可以找到 JavaScript 的信息

+ +

JavaScript 文档包括以下书目:

+ + + +

如果您刚刚开始接触 JavaScript,可以从 JavaScript 指南 开始。一旦掌握了基础知识,您可以从 JavaScript 参考 中获得更多关于特定的对象和语句的细节。

+ +

学习 JavaScript 的窍门

+ +

开始学习 JavaScript 很容易:您只需要一个流行的 Web 浏览器即可。这本指南中包含了一些仅在 Firefox(以及其它基于 Gecko 的浏览器)的近期版本中才有的特性,因此,建议您使用最新的 Firefox 浏览器。

+ +

在Firefox中内嵌了两个用于测验JavaScript非常有效的工具: Web终端和Scratchpad。

+ +

Web终端

+ +

web终端会显示有关当前装载网页的信息,并且还包含命令行,您可以用它在当前的网页中执行 JavaScript 语句。

+ +

要打开 web 终端,请在 Firefox 中的“工具”菜单中选择 “Web Developer“ 中的 "Web Console"。它显示在浏览器窗口的底部。在终端的底部是一个命令行,你可以输入 JavaScript, 而在上面的面板中可以看到输出。

+ +

Image:ErrorConsole.png

+ +

Scratchpad

+ +

Web Console 在执行 JavaScript 的单个命令行时是非常好的,但是在执行多行命令时就没那么方便了,而且你也不可能在 Web Console 中保存你的代码。因此对于更复杂的例子,  Scratchpad 是一个更好的工具。

+ +

 

+ +

要打开 Scratchpad, 可以在 "Web Developer" 菜单下选择 "Scratchpad" , 它在 Firefox 中也位于 "Tools" 菜单下。它是一个单独的窗口以及编辑器,你可以使用它来写和执行浏览器中的代码。你也同样可以将脚本保存在硬盘,并且从硬盘装载。

+ +

如果你选择了 "Inspect",  pad 中的代码会在浏览器中执行,其结果也会以 comment 的形式插入到 pad 中: 

+ +

+ +

文档约定

+ +

JavaScript 应用可以运行在许多操作系统之上;本书中所给出的信息适用于所有这些系统。文件和目录的路径将以 Windows 的形式给出(反斜线用于分隔目录名)。对于 Unix 系统,目录的路径是相同的,只是将反斜线换成斜线即可。

+ +

本指南使用如下形式的统一资源定位符(URL):

+ +

http://server.domain/path/file.html

+ +

在这些 URL 中,server 表示您的应用所运行的服务器的名称,比如 research1 或者 wwwdomain 表示您的互联网域名,比如 netscape.com 或者 uiuc.edupath 表示在服务器中的目录结构;而 file.html 则表示特定的文件名。一般来讲,URL 中的斜体部分为占位符,而其中的等宽字体则为原文。如果您的服务器启用了安全套接字层(SSL),则需要将 URL 中的 http 换成 https。

+ +

本指南使用如下字体约定:

+ + + +
{{ PreviousNext("JavaScript/Guide", "JavaScript/Guide/JavaScript_Overview") }}
diff --git a/files/zh-cn/web/javascript/guide/control_flow_and_error_handling/index.html b/files/zh-cn/web/javascript/guide/control_flow_and_error_handling/index.html new file mode 100644 index 0000000000..b2fe41baef --- /dev/null +++ b/files/zh-cn/web/javascript/guide/control_flow_and_error_handling/index.html @@ -0,0 +1,441 @@ +--- +title: 流程控制与错误处理 +slug: Web/JavaScript/Guide/Control_flow_and_error_handling +tags: + - JavaScript +translation_of: Web/JavaScript/Guide/Control_flow_and_error_handling +--- +

{{jsSidebar("JavaScript Guide")}}{{PreviousNext("Web/JavaScript/Guide/Grammar_and_Types", "Web/JavaScript/Guide/Loops_and_iteration")}}

+ +

JavaScript 提供一套灵活的语句集,特别是控制流语句,你可以用它在你的应用程序中实现大量的交互性功能。本章节我们将带来关于JavaScript语句的一些概览。

+ +

 这一章中的语句,在 JavaScript参考 中包含更为详尽的细节。在 JavaScript 代码中,分号(;)字符被用来分割语句。

+ +

在JavaScript中,任何表达式(expression)都可以看作一条语句(statement),如果你想了解表达式的详细信息,可以阅读表达式与运算符(Expressions and operators)这一章节。

+ +

语句块

+ +

最基本的语句是用于组合语句的语句块。该块由一对大括号界定:

+ +
{
+   statement_1;
+   statement_2;
+   statement_3;
+   .
+   .
+   .
+   statement_n;
+}
+ +

示例

+ +

语句块通常用于流程控制,如ifforwhile等等。

+ +
+
while (x < 10) {
+  x++;
+}
+
+ +

这里{ x++; }就是语句块。

+ +
+

重要:在ECMAScript 6标准之前,Javascript没有块作用域。在一个块中引入的变量的作用域是包含函数或脚本,并且设置它们的效果会延续到块之外。换句话说,块语句不定义范围。JavaScript中的“独立”块会产生与C或Java中完全不同的结果。示例:

+
+ +
var x = 1;
+{
+  var x = 2;
+}
+alert(x); // 输出的结果为 2
+
+ +

这段代码的输出是2,这是因为块级作用域中的 var x变量声明与之前的声明在同一个作用域内。在C语言或是Java语言中,同样的代码输出的结果是1。

+ +

从 ECMAScript 2015 开始,使用 let 和const变量是块作用域的。 更多信息请参考 {{jsxref("Statements/let", "let")}} 和 {{jsxref("Statements/const", "const")}}。

+ +

条件判断语句

+ +

条件判断语句指的是根据指定的条件所返回的结果(真或假或其它预定义的),来执行特定的语句。JavaScript 支持两种条件判断语句:if...elseswitch

+ +

if...else 语句

+ +

当一个逻辑条件为真,用if语句执行一个语句。当这个条件为假,使用可选择的 else 从句来执行这个语句。if 语句如下所示:

+ +
if (condition) {
+  statement_1;
+}else {
+  statement_2;
+} //推荐使用严格的语句块模式,语句else可选
+
+ +

条件可以是任何返回结果被计算为true 或 false的表达式。如果条件表达式返回的是 true,statement_1 语句会被执行;否则,statement_2 被执行。statement_1 和 statement_2 可以是任何语句,甚至你可以将另一个if语句嵌套其中。 

+ +

你也可以组合语句通过使用 else if 来测试连续多种条件判断,就像下面一样:

+ +
if (condition_1) {
+  statement_1;
+}else if (condition_2) {
+  statement_2;
+}else if (condition_n_1) {
+  statement_n;
+}else {
+  statement_last;
+}
+
+ +

要执行多个语句,可以使用语句块({ ... }) 来分组这些语句。通常,总是使用语句块是一个好的习惯,特别是在代码涉及比较多的 if 语句时:

+ +
if (条件) {
+  当条件为真的时候,执行语句1;
+  当条件为真的时候,执行语句2;
+} else {
+  当条件为假的时候,执行语句3;
+  当条件为假的时候,执行语句4;
+}
+
+ +

不建议在条件表达式中使用赋值语句,因为在快速查阅代码时容易把它看成等值比较。例如,不要使用下面的代码:

+ +
+

   if(x = y){

+ +

 /*  语句  */

+ +

}

+
+ +

如果你需要在条件表达式中使用赋值,通常在赋值语句前后额外添加一对括号。例如: 

+ + + +
if ((x = y)) {
+  /* statements here */
+}
+ + + +

错误的值

+ +

下面这些值将被计算出 false (also known as {{Glossary("Falsy")}} values):

+ + + +

当传递给条件语句所有其他的值,包括所有对象会被计算为真 。

+ +

请不要混淆原始的布尔值truefalse 与 {{jsxref("Boolean")}}对象的真和假。例如:

+ +
var b = new Boolean(false);
+if (b) //结果视为真
+if (b == true) // 结果视为假
+ +

示例

+ +

在以下示例中,如果Text对象中的字符数为3,函数checkData将返回true;否则,显示警报并返回false

+ +
function checkData() {
+  if (document.form1.threeChar.value.length == 3) {
+    return true;
+  } else {
+    alert("Enter exactly three characters. " +
+      document.form1.threeChar.value + " is not valid.");
+    return false;
+  }
+}
+
+ +

switch 语句

+ +

switch 语句允许一个程序求一个表达式的值并且尝试去匹配表达式的值到一个 case 标签。如果匹配成功,这个程序执行相关的语句。switch 语句如下所示:

+ +
switch (expression) {
+   case label_1:
+      statements_1
+      [break;]
+   case label_2:
+      statements_2
+      [break;]
+   ...
+   default:
+      statements_def
+      [break;]
+}
+
+ +

程序首先查找一个与 expression 匹配的 case 语句,然后将控制权转移到该子句,执行相关的语句。如果没有匹配值, 程序会去找 default 语句,如果找到了,控制权转移到该子句,执行相关的语句。如果没有找到 default,程序会继续执行 switch 语句后面的语句。default 语句通常出现在switch语句里的最后面,当然这不是必须的。

+ +

可选的 break 语句与每个 case 语句相关联, 保证在匹配的语句被执行后程序可以跳出 switch 并且继续执行 switch 后面的语句。如果break被忽略,则程序将继续执行switch语句中的下一条语句。

+ +

示例
+ 在如下示例中, 如果 fruittype 等于 "Bananas", 程序匹配到对应 "Bananas" 的case 语句,并执行相关语句。 当执行到 break 时,程序结束了 switch 并执行 switch 后面的语句。 如果不写 break ,那么程序将会执行 case "Cherries" 下的语句。

+ +
switch (fruittype) {
+   case "Oranges":
+      document.write("Oranges are $0.59 a pound.<br>");
+      break;
+   case "Apples":
+      document.write("Apples are $0.32 a pound.<br>");
+      break;
+   case "Bananas":
+      document.write("Bananas are $0.48 a pound.<br>");
+      break;
+   case "Cherries":
+      document.write("Cherries are $3.00 a pound.<br>");
+      break;
+   case "Mangoes":
+   case "Papayas":
+      document.write("Mangoes and papayas are $2.79 a pound.<br>");
+      break;
+   default:
+      document.write("Sorry, we are out of " + fruittype + ".<br>");
+}
+document.write("Is there anything else you'd like?<br>");
+
+ +

异常处理语句

+ +

你可以用 throw 语句抛出一个异常并且用 try...catch 语句捕获处理它。

+ + + +

异常类型

+ +

JavaScript 可以抛出任意对象。然而,不是所有对象能产生相同的结果。尽管抛出数值或者字母串作为错误信息十分常见,但是通常用下列其中一种异常类型来创建目标更为高效:

+ + + +

throw 语句

+ +

使用throw语句抛出一个异常。当你抛出异常,你规定一个含有值的表达式要被抛出。

+ +
throw expression;
+
+ +

你可以抛出任意表达式而不是特定一种类型的表达式。下面的代码抛出了几个不同类型的表达式:

+ +
throw "Error2";   // String type
+throw 42;         // Number type
+throw true;       // Boolean type
+throw {toString: function() { return "I'm an object!"; } };
+
+
+ +
注意:你可以在抛出异常时声明一个对象。那你就可以在catch块中查询到对象的属性。 + + +
+ +
// Create an object type UserException
+function UserException (message){
+  this.message=message;
+  this.name="UserException";
+}
+
+// Make the exception convert to a pretty string when used as
+// a string (e.g. by the error console)
+UserException.prototype.toString = function (){
+  return this.name + ': "' + this.message + '"';
+}
+
+// Create an instance of the object type and throw it
+throw new UserException("Value too high");
+ +

try...catch 语句

+ +

try...catch 语句标记一块待尝试的语句,并规定一个以上的响应应该有一个异常被抛出。如果我们抛出一个异常,try...catch语句就捕获它。

+ +

try...catch 语句有一个包含一条或者多条语句的try代码块,0个或1个的catch代码块,catch代码块中的语句会在try代码块中抛出异常时执行。 换句话说,如果你在try代码块中的代码如果没有执行成功,那么你希望将执行流程转入catch代码块。如果try代码块中的语句(或者try 代码块中调用的方法)一旦抛出了异常,那么执行流程会立即进入catch 代码块。如果try代码块没有抛出异常,catch代码块就会被跳过。finally 代码块总会紧跟在try和catch代码块之后执行,但会在try和catch代码块之后的其他代码之前执行。

+ +

下面的例子使用了try...catch语句。示例调用了一个函数用于从一个数组中根据传递值来获取一个月份名称。如果该值与月份数值不相符,会抛出一个带有"InvalidMonthNo"值的异常,然后在捕捉块语句中设monthName变量为unknown

+ +
function getMonthName(mo) {
+  mo = mo - 1; // Adjust month number for array index (1 = Jan, 12 = Dec)
+  var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul",
+                "Aug","Sep","Oct","Nov","Dec"];
+  if (months[mo]) {
+    return months[mo];
+  } else {
+    throw "InvalidMonthNo"; //throw keyword is used here
+  }
+}
+
+try { // statements to try
+  monthName = getMonthName(myMonth); // function could throw exception
+}
+catch (e) {
+  monthName = "unknown";
+  logMyErrors(e); // pass exception object to error handler -> your own function
+}
+ +

catch 块

+ +

你可以使用catch块来处理所有可能在try块中产生的异常。

+ +
catch (catchID) {
+  statements
+}
+
+ +

捕捉块指定了一个标识符(上述语句中的catchID)来存放抛出语句指定的值;你可以用这个标识符来获取抛出的异常信息。在插入throw块时JavaScript创建这个标识符;标识符只存在于catch块的存续期间里;当catch块执行完成时,标识符不再可用。

+ +

举个例子,下面代码抛出了一个异常。当异常出现时跳到catch块。

+ +
try {
+   throw "myException" // generates an exception
+}
+catch (e) {
+// statements to handle any exceptions
+   logMyErrors(e) // pass exception object to error handler
+}
+
+ +

finally

+ +

finally块包含了在try和catch块完成后、下面接着try...catch的语句之前执行的语句。finally块无论是否抛出异常都会执行。如果抛出了一个异常,就算没有异常处理,finally块里的语句也会执行。

+ +

你可以用finally块来令你的脚本在异常发生时优雅地退出;举个例子,你可能需要在绑定的脚本中释放资源。接下来的例子用文件处理语句打开了一个文件(服务端的JavaScript允许你进入文件)。如果在文件打开时一个异常抛出,finally块会在脚本错误之前关闭文件。

+ +
openMyFile();
+try {
+    writeMyFile(theData); //This may throw a error
+}catch(e){
+    handleError(e); // If we got a error we handle it
+}finally {
+    closeMyFile(); // always close the resource
+}
+
+ +

如果finally块返回一个值,该值会是整个try-catch-finally流程的返回值,不管在trycatch块中语句返回了什么:

+ +
function f() {
+  try {
+    console.log(0);
+    throw "bogus";
+  } catch(e) {
+    console.log(1);
+    return true; // this return statement is suspended
+                 // until finally block has completed
+    console.log(2); // not reachable
+  } finally {
+    console.log(3);
+    return false; // overwrites the previous "return"
+    console.log(4); // not reachable
+  }
+  // "return false" is executed now
+  console.log(5); // not reachable
+}
+f(); // console 0, 1, 3; returns false
+
+
+ +

finally块覆盖返回值也适用于在catch块内抛出或重新抛出的异常:

+ +
function f() {
+  try {
+    throw 'bogus';
+  } catch(e) {
+    console.log('caught inner "bogus"');
+    throw e; // this throw statement is suspended until
+             // finally block has completed
+  } finally {
+    return false; // overwrites the previous "throw"
+  }
+  // "return false" is executed now
+}
+
+try {
+  f();
+} catch(e) {
+  // this is never reached because the throw inside
+  // the catch is overwritten
+  // by the return in finally
+  console.log('caught outer "bogus"');
+}
+
+// OUTPUT
+// caught inner "bogus"
+
+ +

嵌套 try...catch 语句

+ +

你可以嵌套一个或多个try ... catch语句。如果一个内部try ... catch语句没有catch块,它需要有一个finally块,并且封闭的try ... catch语句的catch块被检查匹配。有关更多信息,请参阅try... catch参考页上的嵌套try-blocks

+ +

使用Error对象

+ +

根据错误类型,你也许可以用'name'和'message'获取更精炼的信息。'name'提供了常规的错误类(如 'DOMException' 或 'Error'),而'message'通常提供了一条从错误对象转换成字符串的简明信息。

+ +

在抛出你个人所为的异常时,为了充分利用那些属性(比如你的catch块不能分辨是你个人所为的异常还是系统的异常时),你可以使用 Error 构造函数。比如:

+ +
function doSomethingErrorProne () {
+  if (ourCodeMakesAMistake()) {
+    throw (new Error('The message'));
+  } else {
+    doSomethingToGetAJavascriptError();
+  }
+}
+....
+try {
+  doSomethingErrorProne();
+}
+catch (e) {
+  console.log(e.name); // logs 'Error'
+  console.log(e.message); // logs 'The message' or a JavaScript error message)
+}
+ +

Promises

+ +

从 ECMAScript 6 开始,JavaScript 增加了对 {{jsxref("Promise")}} 对象的支持,它允许你对延时和异步操作流进行控制。

+ +

Promise 对象有以下几种状态:

+ + + +

+ +

通过 XHR 加载图片

+ +

你可以在 MDN GitHub promise-test 中找到这个简单的例子,它使用了 Promise 和 XMLHttpRequest 来加载一张图片,你也可以直接在这个页面查看他的效果。同时为了让你更清楚的了解 Promise 和 XHR 的结构,代码中每一个步骤后都附带了注释。

+ +

这里有一个未注释的版本,展现了 Promise 的工作流,希望可以对你的理解有所帮助。

+ +
function imgLoad(url) {
+  return new Promise(function(resolve, reject) {
+    var request = new XMLHttpRequest();
+    request.open('GET', url);
+    request.responseType = 'blob';
+    request.onload = function() {
+      if (request.status === 200) {
+        resolve(request.response);
+      } else {
+        reject(Error('Image didn\'t load successfully; error code:'
+                     + request.statusText));
+      }
+    };
+    request.onerror = function() {
+      reject(Error('There was a network error.'));
+    };
+    request.send();
+  });
+}
+ +

若想了解更详细的信息,请参阅 {{jsxref("Promise")}} 页面。

+ +
{{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
diff --git a/files/zh-cn/web/javascript/guide/details_of_the_object_model/index.html b/files/zh-cn/web/javascript/guide/details_of_the_object_model/index.html new file mode 100644 index 0000000000..f140ba8e84 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/details_of_the_object_model/index.html @@ -0,0 +1,758 @@ +--- +title: 对象模型的细节 +slug: Web/JavaScript/Guide/Details_of_the_Object_Model +tags: + - JavaScript + - Object + - 中级 + - 教程 +translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Using_promises")}}
+ +

JavaScript 是一种基于原型而不是基于类的基于对象(object-based)语言。正是由于这一根本的区别,其如何创建对象的层级结构以及对象的属性与属性值是如何继承的并不是那么清晰。本节试着阐明。

+ +

本节假设您已经有一些 JavaScript 基础,并且用 JavaScript 函数创建过简单的对象。

+ +

基于类 vs 基于原型的语言

+ +

基于类的面向对象语言,比如 Java 和 C++,是构建在两个不同实体之上的:类和实例。

+ + + +

基于原型的语言(如 JavaScript)并不存在这种区别:它只有对象。基于原型的语言具有所谓原型对象(prototypical object)的概念。原型对象可以作为一个模板,新对象可以从中获得原始的属性。任何对象都可以指定其自身的属性,既可以是创建时也可以在运行时创建。而且,任何对象都可以作为另一个对象的原型(prototype),从而允许后者共享前者的属性。

+ +

定义类

+ +

在基于类的语言中,需要专门的类定义(class definition)来定义类。在定义类时,允许定义被称为构造器(constructor)的特殊的方法来创建该类的实例。在构造器方法中,可以指定实例的属性的初始值并做一些其他的操作。你可以通过使用 new 操作符来创建类的实例。

+ +

JavaScript 大体上与之类似,但并没有专门的类定义,你通过定义构造函数的方式来创建一系列有着特定初始值和方法的对象。任何JavaScript函数都可以被用作构造函数。你也可以使用 new 操作符来创建一个新对象。

+ +
+

提示:在ES6中引入了 类定义 ,但它实际上是已有的原型继承方式的语法糖而已,并没有引入新的面向对象继承模型。

+
+ +

子类和继承

+ +

基于类的语言是通过对类的定义中构建类的层级结构的。在类定义中,可以指定新的类是一个现存的类的子类。子类将继承父类的全部属性,并可以添加新的属性或者修改继承的属性。例如,假设 Employee 类只有 namedept 属性,而 ManagerEmployee 的子类并添加了 reports 属性。这时,Manager 类的实例将具有所有三个属性:namedeptreports

+ +

JavaScript 通过将构造器函数与原型对象相关联的方式来实现继承。这样,您可以创建完全一样的 EmployeeManager 示例,不过需要使用略微不同的术语。首先,定义Employee构造函数,在该构造函数内定义name、dept属性;接下来,定义Manager构造函数,在该构造函数内调用Employee构造函数,并定义reports属性;最后,将一个获得了Employee.prototype(Employee构造函数原型)的新对象赋予manager构造函数,以作为Manager构造函数的原型。之后当你创建新的Manager对象实例时,该实例会从Employee对象继承name、dept属性。

+ +

添加和移除属性

+ +

在基于类的语言中,通常在编译时创建类,然后在编译时或者运行时对类的实例进行实例化。一旦定义了类,无法对类的属性进行更改。然而,在 JavaScript 中,允许运行时添加或者移除任何对象的属性。如果您为一个对象中添加了一个属性,而这个对象又作为其它对象的原型,则以该对象作为原型的所有其它对象也将获得该属性。

+ +

差异总结

+ +

下面的表格摘要给出了上述区别。本节的后续部分将描述有关使用 JavaScript 构造器和原型创建对象层级结构的详细信息,并将其与在 Java 中的做法加以对比。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
基于类(Java)和基于原型(JavaScript)的对象系统的比较
基于类的(Java)基于原型的(JavaScript)
类和实例是不同的事物。所有对象均为实例。
通过类定义来定义类;通过构造器方法来实例化类。通过构造器函数来定义和创建一组对象。
通过 new 操作符创建单个对象。相同。
通过类定义来定义现存类的子类,从而构建对象的层级结构。指定一个对象作为原型并且与构造函数一起构建对象的层级结构
遵循类链继承属性。遵循原型链继承属性。
类定义指定类的所有实例的所有属性。无法在运行时动态添加属性。构造器函数或原型指定实例的初始属性集。允许动态地向单个的对象或者整个对象集中添加或移除属性。
+ +

Employee 示例

+ +

本节的余下部分将使用如下图所示的 Employee 层级结构。

+ +

+ +
+ +
+ +

创建层级结构

+ +

可以有几种不同的方式来定义适当的构造器函数,从而实现雇员的层级结构。如何选择很大程度上取决于您希望在您的应用程序中能做到什么。

+ +

本节介绍了如何使用非常简单的(同时也是相当不灵活的)定义,使得继承得以实现。在定义完成后,就无法在创建对象时指定属性的值。新创建的对象仅仅获得了默认值,当然允许随后加以修改。图例 8.2 展现了这些简单的定义形成的层级结构。

+ +

在实际应用程序中,您很可能想定义构造器,以允许您在创建对象时指定属性值。(参见More flexible constructors)。当前,这些简单的定义只是说明了继承是如何实现的。

+ +

下面关于 Employee 的 Java 和 JavaScript 的定义是非常类似的。唯一的不同是在 Java 中需要指定每个属性的类型,而在 JavaScript 中则不需要(这是因为Java是 强类型 语言,而 JavaScript 是弱类型语言)。

+ + + + + + + + + + + + + + +
JavaScriptJava
+
+function Employee () {
+  this.name = "";
+  this.dept = "general";
+}
+
+
+
+public class Employee {
+   public String name = "";
+   public String dept = "general";
+}
+
+ +

Manager 和 WorkerBee 的定义表示在如何指定继承链中上一层对象时,两者存在不同点。在 JavaScript 中,您会添加一个原型实例作为构造器函数prototype 属性的值,然后将该构造函数原型的构造器重载为其自身。这一动作可以在构造器函数定义后的任意时刻执行。而在 Java 中,则需要在类定义中指定父类,且不能在类定义之外改变父类。

+ + + + + + + + + + + + + + +
JavaScriptJava
+
+function Manager() {
+  Employee.call(this);
+  this.reports = [];
+}
+Manager.prototype = Object.create(Employee.prototype);
+
+function WorkerBee() {
+  Employee.call(this);
+  this.projects = [];
+}
+WorkerBee.prototype = Object.create(Employee.prototype);
+
+
+public class Manager extends Employee {
+   public Employee[] reports = new Employee[0];
+}
+
+
+
+public class WorkerBee extends Employee {
+   public String[] projects = new String[0];
+}
+
+ +

在对EngineerSalesPerson 定义时,创建了继承自 WorkerBee 的对象,该对象会进而继承自Employee。这些对象会具有在这个链之上的所有对象的属性。另外,它们在定义时,又重载了继承的 dept 属性值,赋予新的属性值。

+ + + + + + + + + + + + + + +
JavaScriptJava
+
+function SalesPerson() {
+   WorkerBee.call(this);
+   this.dept = 'sales';
+   this.quota = 100;
+}
+SalesPerson.prototype = Object.create(WorkerBee.prototype);
+
+function Engineer() {
+   WorkerBee.call(this);
+   this.dept = 'engineering';
+   this.machine = '';
+}
+Engineer.prototype = Object.create(WorkerBee.prototype);
+
+
+public class SalesPerson extends WorkerBee {
+   public String dept = "sales";
+   public double quota = 100.0;
+}
+
+
+public class Engineer extends WorkerBee {
+   public String dept = "engineering";
+   public String machine = "";
+}
+
+ +

使用这些定义,您可以创建这些对象的实例,以获取其属性的默认值。下图说明了如何使用这些 JavaScript 定义创建新对象并显示新对象的属性值。

+ +
+

提示:实例在基于类的语言中具有特定的技术含义。在这些语言中,一个实例是一个类的单独实例化,与一个类本质上是不同的。在 JavaScript 中,“实例”没有这个技术含义,因为JavaScript在类和实例之间不存在这样的区别。然而,在讨论 JavaScript 时,可以非正式地使用“实例”来表示使用特定构造函数创建的对象。 所以,在这个例子中,你可以非正式地说janeEngineer的一个实例。同样,虽然术语 parent,child,ancestor 和 descendant 在 JavaScript 中没有正式含义;你可以非正式地使用它们来引用原型链中较高或更低的对象。

+
+ +

用简单的定义创建对象

+ +

对象层次结构

+ +

使用右侧的代码创建以下层次结构。

+ +

+ +

个别对象

+ +
var jim = new Employee; // 如构造函数无须接受任何参数,圆括号可以省略。
+// jim.name is ''
+// jim.dept is 'general'
+
+var sally = new Manager;
+// sally.name is ''
+// sally.dept is 'general'
+// sally.reports is []
+
+var mark = new WorkerBee;
+// mark.name is ''
+// mark.dept is 'general'
+// mark.projects is []
+
+var fred = new SalesPerson;
+// fred.name is ''
+// fred.dept is 'sales'
+// fred.projects is []
+// fred.quota is 100
+
+var jane = new Engineer;
+// jane.name is ''
+// jane.dept is 'engineering'
+// jane.projects is []
+// jane.machine is ''
+ +

对象的属性

+ +

本节将讨论对象如何从原型链中的其它对象中继承属性,以及在运行时添加属性的相关细节。

+ +

继承属性

+ +

假设您通过如下语句创建一个mark对象作为 WorkerBee的实例:

+ +
var mark = new WorkerBee;
+
+ +

当 JavaScript 执行 new 操作符时,它会先创建一个普通对象,并将这个普通对象中的 [[prototype]] 指向 WorkerBee.prototype ,然后再把这个普通对象设置为执行 WorkerBee 构造函数时 this  的值。该普通对象的 [[Prototype]] 决定其用于检索属性的原型链。当构造函数执行完成后,所有的属性都被设置完毕,JavaScript 返回之前创建的对象,通过赋值语句将它的引用赋值给变量 mark

+ +

这个过程不会显式的将 mark所继承的原型链中的属性作为本地属性存放在 mark 对象中。当访问属性时,JavaScript 将首先检查对象自身中是否存在该属性,如果有,则返回该属性的值。如果不存在,JavaScript会检查原型链(使用内置的 [[Prototype]] )。如果原型链中的某个对象包含该属性,则返回这个属性的值。如果遍历整条原型链都没有找到该属性,JavaScript 则认为对象中不存在该属性,返回一个 undefined。这样,mark 对象中将具有如下的属性和对应的值:

+ +
mark.name = "";
+mark.dept = "general";
+mark.projects = [];
+
+ +

mark 对象从 mark.__proto__ 中保存的原型对象里继承了 namedept 属性。并由 WorkerBee 构造函数为 projects 属性设置了本地值。 这就是 JavaScript 中的属性和属性值的继承。这个过程的一些微妙之处将在 Property inheritance revisited 中进一步讨论。

+ +

由于这些构造器不支持为实例设置特定的值,所以这些属性值仅仅是创建自 WorkerBee 的所有对象所共享的默认值。当然这些属性的值是可以修改的,所以您可以为 mark指定特定的信息,如下所示:

+ +
mark.name = "Doe, Mark";
+mark.dept = "admin";
+mark.projects = ["navigator"];
+ +

添加属性

+ +

在 JavaScript 中,您可以在运行时为任何对象添加属性,而不必受限于构造函数提供的属性。添加特定于某个对象的属性,只需要为该对象指定一个属性值,如下所示:

+ +
mark.bonus = 3000;
+
+ +

这样 mark 对象就有了 bonus 属性,而其它 WorkerBee 则没有该属性。

+ +

如果您向某个构造函数的原型对象中添加新的属性,那么该属性将添加到从这个原型中继承属性的所有对象的中。例如,可以通过如下的语句向所有雇员中添加 specialty 属性:

+ +
Employee.prototype.specialty = "none";
+
+ +

只要 JavaScript 执行了该语句,则 mark 对象也将具有 specialty 属性,其值为 "none"。下图则表示了在 Employee 原型中添加该属性,然后在 Engineer 的原型中重载该属性的效果。

+ +


+ 添加属性

+ +

更灵活的构造器

+ +

到目前为止,本文所展示的构造函数都不能让你在创建新实例时为其制定属性值。其实我们也可以像 Java 一样,为构造器提供参数以初始化实例的属性值。下图展示了一种实现方式。

+ +


+ Specifying properties in a constructor, take 1

+ +

下面的表格中罗列了这些对象在 Java 和 JavaScript 中的定义。

+ + + + + + + + + + + + + + + + + + + + + + +
JavaScriptJava
+
+function Employee (name, dept) {
+  this.name = name || "";
+  this.dept = dept || "general";
+}
+
+
+
+public class Employee {
+   public String name;
+   public String dept;
+   public Employee () {
+      this("", "general");
+   }
+   public Employee (String name) {
+      this(name, "general");
+   }
+   public Employee (String name, String dept) {
+      this.name = name;
+      this.dept = dept;
+   }
+}
+
+
+
+function WorkerBee (projs) {
+  this.projects = projs || [];
+}
+WorkerBee.prototype = new Employee;
+
+
+
+public class WorkerBee extends Employee {
+   public String[] projects;
+   public WorkerBee () {
+      this(new String[0]);
+   }
+   public WorkerBee (String[] projs) {
+      projects = projs;
+   }
+}
+
+
+
+
+
+function Engineer (mach) {
+   this.dept = "engineering";
+   this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+
+
+
+public class Engineer extends WorkerBee {
+   public String machine;
+   public Engineer () {
+      dept = "engineering";
+      machine = "";
+   }
+   public Engineer (String mach) {
+      dept = "engineering";
+      machine = mach;
+   }
+}
+
+
+ +

上面使用 JavaScript 定义过程使用了一种设置默认值的特殊惯用法:

+ +
this.name = name || "";
+
+ +

JavaScript 的逻辑或操作符(||)会对第一个参数进行判断。如果该参数值运算后结果为真,则操作符返回该值。否则,操作符返回第二个参数的值。因此,这行代码首先检查 name 是否是对name 属性有效的值。如果是,则设置其为 this.name 的值。否则,设置 this.name 的值为空的字符串。尽管这种用法乍看起来有些费解,为了简洁起见,本章将使用这种习惯用法。

+ +
+

提示:如果调用构造函数时,指定了可以转换为 false 的参数(比如0和空字符串),结果可能出乎调用者意料。此时,将使用默认值(译注:不是指定的参数值 0 和 "")。

+
+ +

使用这些定义,当创建对象的实例时,可以为本地定义的属性指定值。你可以使用以下语句创建一个新的Engineer

+ +
var jane = new Engineer("belau");
+
+ +

此时,Jane 的属性如下所示:

+ +
jane.name == "";
+jane.dept == "engineering";
+jane.projects == [];
+jane.machine == "belau"
+
+ +

注意,由上面对类的定义,您无法为诸如 name 这样的继承属性指定初始值。如果想在 JavaScript 中为继承的属性指定初始值,您需要在构造函数中添加更多的代码。

+ +

到目前为止,构造函数已经能够创建一个普通对象,然后为新对象指定本地的属性和属性值。您还可以通过直接调用原型链上的更高层次对象的构造函数,让构造器添加更多的属性。下图即实现了这一功能。

+ +


+ Specifying properties in a constructor, take 2

+ +

我们来详细看一下这些定义。这是Engineer构造函数的新定义:

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+ +

假设您创建了一个新的 Engineer 对象,如下所示:

+ +
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+
+ +

JavaScript 会按以下步骤执行:

+ +
    +
  1. new 操作符创建了一个新的对象,并将其 __proto__ 属性设置为 Engineer.prototype
  2. +
  3. new 操作符将该新对象作为 this 的值传递给 Engineer 构造函数。
  4. +
  5. 构造函数为该新对象创建了一个名为 base 的新属性,并指向 WorkerBee 的构造函数。这使得 WorkerBee 构造函数成为 Engineer 对象的一个方法。base 属性的名称并没有什么特殊性,我们可以使用任何其他合法的名称来代替;base 仅仅是为了贴近它的用意。
  6. +
  7. +

    构造函数调用 base 方法,将传递给该构造函数的参数中的两个,作为参数传递给 base 方法,同时还传递一个字符串参数  "engineering"。显式地在构造函数中使用 "engineering" 表明所有 Engineer 对象继承的 dept 属性具有相同的值,且该值重载了继承自 Employee 的值。

    +
  8. +
  9. +

    因为 baseEngineer 的一个方法,在调用 base 时,JavaScript 将在步骤 1 中创建的对象绑定给 this 关键字。这样,WorkerBee 函数接着将 "Doe, Jane""engineering" 参数传递给 Employee 构造函数。当从 Employee 构造函数返回时,WorkerBee 函数用剩下的参数设置 projects 属性。

    +
  10. +
  11. 当从 base 方法返回后,Engineer 构造函数将对象的 machine 属性初始化为 "belau"
  12. +
  13. 当从构造函数返回时,JavaScript 将新对象赋值给 jane 变量。
  14. +
+ +

你可以认为,在 Engineer 的构造器中调用了 WorkerBee 的构造器,也就为 Engineer 对象设置好了继承关系。事实并非如此。调用 WorkerBee 构造器确保了Engineer 对象以所有在构造器中所指定的属性被调用。但是,如果后续在 Employee 或者 WorkerBee 原型中添加了属性,那些属性不会被 Engineer 对象继承。例如,假设如下语句:

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+Employee.prototype.specialty = "none";
+
+ +

对象 jane 不会继承 specialty 属性。您必须显式地设置原型才能确保动态的继承。如果修改成如下的语句:

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+Employee.prototype.specialty = "none";
+
+ +

现在 jane 对象的 specialty 属性为 "none" 了。

+ +

继承的另一种途径是使用call() / apply() 方法。下面的方式都是等价的:

+ + + + + + + + +
+
+function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+
+
+function Engineer (name, projs, mach) {
+  WorkerBee.call(this, name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+
+ +

使用 javascript 的 call() 方法相对明了一些,因为无需 base 方法了。

+ +

再谈属性的继承

+ +

前面的小节中描述了 JavaScript 构造器和原型如何提供层级结构和继承的实现。本节中对之前未讨论的一些细节进行阐述。

+ +

本地值和继承值

+ +

正如本章前面所述,在访问一个对象的属性时,JavaScript 将执行下面的步骤:

+ +
    +
  1. 检查对象自身是否存在。如果存在,返回值。
  2. +
  3. 如果本地值不存在,检查原型链(通过 __proto__ 属性)。
  4. +
  5. 如果原型链中的某个对象具有指定属性,则返回值。
  6. +
  7. 如果这样的属性不存在,则对象没有该属性,返回 undefined。
  8. +
+ +

以上步骤的结果依赖于你是如何定义的。最早的例子中有如下定义:

+ +
function Employee () {
+  this.name = "";
+  this.dept = "general";
+}
+
+function WorkerBee () {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+ +

基于这些定义,假定通过如下的语句创建 WorkerBee 的实例 amy

+ +
var amy = new WorkerBee;
+
+ +

amy 对象将具有一个本地属性 projectsnamedept 则不是 amy 对象的本地属性,而是从 amy 对象的 __proto__ 属性获得的。因此,amy 将具有如下的属性值:

+ +
amy.name == "";
+amy.dept == "general";
+amy.projects == [];
+
+ +

现在,假设修改了与 Employee 的相关联原型中的 name 属性的值:

+ +
Employee.prototype.name = "Unknown"
+
+ +

乍一看,你可能觉得新的值会传播给所有 Employee 的实例。然而,并非如此。

+ +

在创建 Employee 对象的任意实例时,该实例的 name 属性将获得一个本地值(空的字符串)。这就意味着在创建一个新的 Employee 对象作为 WorkerBee 的原型时,WorkerBee.prototypename 属性将具有一个本地值。因此,当 JavaScript 查找 amy 对象(WorkerBee 的实例)的 name 属性时,JavaScript 将找到 WorkerBee.prototype 中的本地值。因此,也就不会继续在原型链中向上找到 Employee.prototype 了。

+ +

如果想在运行时修改一个对象的属性值并且希望该值被所有该对象的后代所继承,您就不能在该对象的构造器函数中定义该属性。而应该将该属性添加到该对象所关联的原型中。例如,假设将前面的代码作如下修改:

+ +
function Employee () {
+  this.dept = "general";
+}
+Employee.prototype.name = "";
+
+function WorkerBee () {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+var amy = new WorkerBee;
+
+Employee.prototype.name = "Unknown";
+
+ +

在这种情况下,amyname 属性将为 "Unknown"。

+ +

正如这些例子所示,如果希望对象的属性具有默认值,并且希望在运行时修改这些默认值,应该在对象的原型中设置这些属性,而不是在构造器函数中。

+ +

判断实例的关系

+ +

JavaScript 的属性查找机制首先在对象自身的属性中查找,如果指定的属性名称没有找到,将在对象的特殊属性 __proto__ 中查找。这个过程是递归的;被称为“在原型链中查找”。

+ +

特殊的 __proto__ 属性是在构建对象时设置的;设置为构造器的 prototype 属性的值。所以表达式 new Foo() 将创建一个对象,其 __proto__ == Foo.prototype。因而,修改 Foo.prototype 的属性,将改变所有通过 new Foo() 创建的对象的属性的查找。

+ +

每个对象都有一个 __proto__ 对象属性(除了 Object);每个函数都有一个 prototype 对象属性。因此,通过“原型继承”,对象与其它对象之间形成关系。通过比较对象的 __proto__ 属性和函数的 prototype 属性可以检测对象的继承关系。JavaScript 提供了便捷方法:instanceof 操作符可以用来将一个对象和一个函数做检测,如果对象继承自函数的原型,则该操作符返回真。例如:

+ +
var f = new Foo();
+var isTrue = (f instanceof Foo);
+ +

作为详细一点的例子,假定我们使用和在 Inheriting properties 中相同的一组定义。创建 Engineer 对象如下:

+ +
var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
+
+ +

对于该对象,以下所有语句均为真:

+ +
chris.__proto__ == Engineer.prototype;
+chris.__proto__.__proto__ == WorkerBee.prototype;
+chris.__proto__.__proto__.__proto__ == Employee.prototype;
+chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
+chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
+
+ +

基于此,可以写出一个如下所示的 instanceOf 函数:

+ +
function instanceOf(object, constructor) {
+   while (object != null) {
+      if (object == constructor.prototype)
+         return true;
+      if (typeof object == 'xml') {
+        return constructor.prototype == XML.prototype;
+      }
+      object = object.__proto__;
+   }
+   return false;
+}
+
+ +
Note: 在上面的实现中,检查对象的类型是否为 "xml" 的目的在于解决新近版本的 JavaScript 中表达 XML 对象的特异之处。如果您想了解其中琐碎细节,可以参考 {{ bug(634150) }}。
+ +
使用上面定义的 instanceOf 函数,这些表达式为真:
+ +
+ +
instanceOf (chris, Engineer)
+instanceOf (chris, WorkerBee)
+instanceOf (chris, Employee)
+instanceOf (chris, Object)
+
+ +

但如下表达式为假:

+ +
instanceOf (chris, SalesPerson)
+ +

构造器中的全局信息

+ +

在创建构造器时,在构造器中设置全局信息要小心。例如,假设希望为每一个雇员分配一个唯一标识。可能会为 Employee 使用如下定义:

+ +
var idCounter = 1;
+
+function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   this.id = idCounter++;
+}
+
+ +

基于该定义,在创建新的 Employee 时,构造器为其分配了序列中的下一个标识符。然后递增全局的标识符计数器。因此,如果,如果随后的语句如下,则 victoria.id 为 1 而 harry.id 为 2:

+ +
var victoria = new Employee("Pigbert, Victoria", "pubs")
+var harry = new Employee("Tschopik, Harry", "sales")
+
+ +

乍一看似乎没问题。但是,无论什么目的,在每一次创建 Employee 对象时,idCounter 都将被递增一次。如果创建本章中所描述的整个 Employee 层级结构,每次设置原型的时候,Employee 构造器都将被调用一次。假设有如下代码:

+ +
var idCounter = 1;
+
+function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   this.id = idCounter++;
+}
+
+function Manager (name, dept, reports) {...}
+Manager.prototype = new Employee;
+
+function WorkerBee (name, dept, projs) {...}
+WorkerBee.prototype = new Employee;
+
+function Engineer (name, projs, mach) {...}
+Engineer.prototype = new WorkerBee;
+
+function SalesPerson (name, projs, quota) {...}
+SalesPerson.prototype = new WorkerBee;
+
+var mac = new Engineer("Wood, Mac");
+
+ +

还可以进一步假设上面省略掉的定义中包含 base 属性而且调用了原型链中高于它们的构造器。即便在现在这个情况下,在 mac 对象创建时,mac.id 为 5。

+ +

依赖于应用程序,计数器额外的递增可能有问题,也可能没问题。如果确实需要准确的计数器,则以下构造器可以作为一个可行的方案:

+ +
function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   if (name)
+      this.id = idCounter++;
+}
+
+ +

在用作原型而创建新的 Employee 实例时,不会指定参数。使用这个构造器定义,如果不指定参数,构造器不会指定标识符,也不会递增计数器。而如果想让 Employee 分配到标识符,则必需为雇员指定姓名。在这个例子中,mac.id 将为 1。

+ +

或者,您可以创建一个 Employee 的原型对象的副本以分配给 WorkerBee:

+ +
WorkerBee.prototype = Object.create(Employee.prototype);
+// instead of WorkerBee.prototype = new Employee
+ +

没有多重继承

+ +

某些面向对象语言支持多重继承。也就是说,对象可以从无关的多个父对象中继承属性和属性值。JavaScript 不支持多重继承。

+ +

JavaScript 属性值的继承是在运行时通过检索对象的原型链来实现的。因为对象只有一个原型与之关联,所以 JavaScript 无法动态地从多个原型链中继承。

+ +

在 JavaScript 中,可以在构造器函数中调用多个其它的构造器函数。这一点造成了多重继承的假象。例如,考虑如下语句:

+ +
function Hobbyist (hobby) {
+   this.hobby = hobby || "scuba";
+}
+
+function Engineer (name, projs, mach, hobby) {
+   this.base1 = WorkerBee;
+   this.base1(name, "engineering", projs);
+   this.base2 = Hobbyist;
+   this.base2(hobby);
+   this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+
+var dennis = new Engineer("Doe, Dennis", ["collabra"], "hugo")
+
+ +

进一步假设使用本章前面所属的 WorkerBee 的定义。此时 dennis 对象具有如下属性:

+ +
dennis.name == "Doe, Dennis"
+dennis.dept == "engineering"
+dennis.projects == ["collabra"]
+dennis.machine == "hugo"
+dennis.hobby == "scuba"
+
+ +

dennis 确实从 Hobbyist 构造器中获得了 hobby 属性。但是,假设添加了一个属性到 Hobbyist 构造器的原型:

+ +
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
+
+ +

dennis 对象不会继承这个新属性。

+ +
{{ PreviousNext("JavaScript/Guide/Predefined_Core_Objects", "JavaScript/Guide/Inheritance_Revisited") }}
diff --git a/files/zh-cn/web/javascript/guide/expressions_and_operators/index.html b/files/zh-cn/web/javascript/guide/expressions_and_operators/index.html new file mode 100644 index 0000000000..b7e809269d --- /dev/null +++ b/files/zh-cn/web/javascript/guide/expressions_and_operators/index.html @@ -0,0 +1,984 @@ +--- +title: 表达式与运算符 +slug: Web/JavaScript/Guide/Expressions_and_Operators +tags: + - JavaScript + - 入门 + - 指南 + - 表达式 +translation_of: Web/JavaScript/Guide/Expressions_and_Operators +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}}
+ +

本章描述了 JavaScript 的表达式和运算符,包括了赋值,比较,算数,位运算,逻辑,字符串,三元等等。

+ +

一个完整详细的运算符列表和表达式可以参见 reference.

+ +

运算符

+ +

JavaScript 拥有如下类型的运算符。本节描述了运算符和运算符的优先级。

+ + + +

JavaScript 拥有二元和一元运算符, 和一个特殊的三元运算符(条件运算符)。一个二元运算符需要两个操作数,分别在运算符的前面和后面:

+ +
操作数1 运算符 操作数2
+
+ +

例如, 3+4x*y

+ +

一个一元运算符需要一个操作数,在运算符前面或后面:

+ +
运算符 操作数
+ +

+ +
操作数 运算符
+ +

例如, x++++x

+ +

赋值运算符

+ +

一个 赋值运算符(assignment operator) 将它右边操作数的值赋给它左边的操作数。最简单的赋值运算符是等于(=),它将右边的操作数值赋给左边的操作数。那么 x = y 就是将 y 的值赋给 x。

+ +

还有一些复合赋值操作符,它们是下表列出的这些操作的缩写:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
复合赋值运算符
名字简写的操作符含义
赋值(Assignment)x = yx = y
加法赋值(Addition assignment)x += yx = x + y
减法赋值(Subtraction assignment)x -= yx = x - y
乘法赋值(Multiplication assignment)x *= yx = x * y
除法赋值(Division assignment)x /= yx = x / y
求余赋值(Remainder assignment)x %= yx = x % y
求幂赋值(Exponentiation assignment)x **= yx = x ** y
左移位赋值(Left shift assignment)x <<= yx = x << y
右移位赋值(Right shift assignment)x >>= yx = x >> y
无符号右移位赋值(Unsigned right shift assignment)x >>>= yx = x >>> y
按位与赋值(Bitwise AND assignment)x &= yx = x & y
按位异或赋值(Bitwise XOR assignment)x ^= yx = x ^ y
按位或赋值(Bitwise OR assignment)x |= yx = x | y
+ +

解构

+ +

对于更复杂的赋值,解构赋值语法是一个能从数组或对象对应的数组结构或对象字面量里提取数据的 Javascript 表达式。

+ +
var foo = ["one", "two", "three"];
+
+// 不使用解构
+var one   = foo[0];
+var two   = foo[1];
+var three = foo[2];
+
+// 使用解构
+var [one, two, three] = foo;
+ +

比较运算符

+ +

比较运算符比较它的操作数并返回一个基于表达式是否为真的逻辑值。操作数可以是数字,字符串,逻辑,对象值。字符串比较是基于标准的字典顺序,使用Unicode值。在多数情况下,如果两个操作数不是相同的类型, JavaScript 会尝试转换它们为恰当的类型来比较。这种行为通常发生在数字作为操作数的比较。类型转换的例外是使用 ===!== 操作符,它们会执行严格的相等和不相等比较。这些运算符不会在检查相等之前转换操作数的类型。下面的表格描述了该示例代码中的各比较运算符

+ +
var var1 = 3;
+var var2 = 4;
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
比较运算符
运算符描述返回true的示例
等于 Equal (==) +

如果两边操作数相等时返回true。

+
3 == var1 +

"3" == var1

+ 3 == '3'
不等于 Not equal (!=)如果两边操作数不相等时返回truevar1 != 4
+ var2 != "3"
全等 Strict equal (===)两边操作数相等且类型相同时返回true。 参见 {{jsxref("Object.is")}} and sameness in JS.3 === var1
不全等 Strict not equal (!==)两边操作数不相等或类型不同时返回true。var1 !== "3"
+ 3 !== '3'
大于 Greater than (>)左边的操作数大于右边的操作数返回truevar2 > var1
+ "12" > 2
大于等于 Greater than or equal (>=)左边的操作数大于或等于右边的操作数返回truevar2 >= var1
+ var1 >= 3
小于 Less than (<)左边的操作数小于右边的操作数返回truevar1 < var2
+ "2" < 12
小于等于 Less than or equal (<=)左边的操作数小于或等于右边的操作数返回truevar1 <= var2
+ var2 <= 5
+ +
+

注意: =>) 不是运算符,而是箭头函数的标记符号 。

+
+ +

算术运算符

+ +

算术运算符使用数值(字面量或者变量)作为操作数并返回一个数值.标准的算术运算符就是加减乘除(+ - * /)。当操作数是浮点数时,这些运算符表现得跟它们在大多数编程语言中一样(特殊要注意的是,除零会产生{{jsxref("Infinity")}})。例如:

+ +
1 / 2;  // 0.5
+1 / 2 == 1.0 / 2.0; // true
+
+ +

除了标准的算术运算符(+, - ,* /),JavaScript还提供了下表中的算术运算符。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
表 3.3 算术运算符
OperatorDescriptionExample
求余(%)二元运算符. 返回相除之后的余数.12 % 5 返回 2。
自增(++)一元运算符. 将操作数的值加一. 如果放在操作数前面 (++x), 则返回加一后的值; 如果放在操作数后面 (x++), 则返回操作数原值,然后再将操作数加一. +

var x=3;

+ +

console.log(++x); //4

+ +

console.log(x); //4

+ +

var y=3;

+ +

console.log(y++); //3

+ +

console.log(y); //4

+
自减(--)一元运算符. 将操作数的值减一. 前后缀两种用法的返回值类似自增运算符. +

var x=3; console.log(--x); //输入2,x=2

+ +

var y=3;console.log(y--);//输出3,x=2;

+
一元负值符(-)一元运算符,返回操作数的负值. +

var x=3; console.log(-x); //输入-3

+
+

一元正值符(+)

+
一元运算符, 如果操作数在之前不是number,试图将其转换为number +

console.log( +'3' ); // 3

+ +

console.log( '3' ); // '3'

+ +

console.log(+true); // 1

+
指数运算符(**)计算 base(底数) 的 exponent(指数)次方, 表示为baseexponent +

2 ** 3 returns 8.
+ 10 ** -1 returns 0.1.

+
+ +

位运算符

+ +

位运算符将它的操作数视为32位元的二进制串(0和1组成)而非十进制八进制或十六进制数。例如:十进制数字9用二进制表示为1001,位运算符就是在这个二进制表示上执行运算,但是返回结果是标准的JavaScript数值。

+ +

下表总结了 JavaScript 的位运算符。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
位运算符
OperatorUsageDescription
按位与 ANDa & b +

在a,b的位表示中,每一个对应的位都为1则返回1, 否则返回0.

+
按位或 ORa | b在a,b的位表示中,每一个对应的位,只要有一个为1则返回1, 否则返回0.
按位异或 XORa ^ b在a,b的位表示中,每一个对应的位,两个不相同则返回1,相同则返回0.
按位非 NOT~ a反转被操作数的位。
左移 shifta << b将a的二进制串向左移动b位,右边移入0.
算术右移a >> b +

把a的二进制表示向右移动b位,丢弃被移出的所有位.

+ +

(译注:算术右移左边空出的位是根据最高位是0和1来进行填充的)

+
+

无符号右移

+ +

(左边空出位用0填充)

+
a >>> b把a的二进制表示向右移动b位,丢弃被移出的所有位,并把左边空出的位都填充为0
+ +

位逻辑运算符

+ +

概念上来讲, 位逻辑运算符工作流程如下:

+ + + +
+
+
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+
+
+ + + +

例如,十进制数9的二进制表示是1001,十进制数15的二进制表示是1111.因此,当位运算符应用到这两个值时,结果如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
位运算符范例
表达式结果二进制描述
15 & 991111 & 1001 = 1001
15 | 9151111 | 1001 = 1111
15 ^ 961111 ^ 1001 = 0110
~15-16~00000000...00001111 = 11111111...11110000
~9-10~00000000...00001001 = 11111111...11110110
+ +

注意位运算符“非”将所有的32位取反,而值的最高位(最左边的一位)为1则表示负数(2-补码表示法)。

+ +

移位运算符

+ +

移位运算符带两个操作数:第一个是待移位的数,第二个是指定第一个数要被移多少位的数。移位的方向由运算符来控制.

+ +

移位运算符把操作数转为32bit整数,然后得出一个与待移位数相同种类的值。

+ +

移位运算符列表如下。

+ +

移位运算符

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符描述范例
<<
+ (左移位)
将第一个操作数向左移动指定数量的位. 左边移出位被抛弃. 左边移出的几位被丢弃.右边多出的空位由0补齐9<<2产生36,因为1001移位2比特向左变为100100,它是36。
>>
+ (带符号右移)
将第一个操作数向右移动指定数量的位. 右边移出位被抛弃. 左边多出的空位由原值的最左边数字补齐.9>>2产生2,因为1001移位2位向右变为10,其是2。同样,-9>>2产生-3,由于符号被保留。
>>>
+ (补零右移)
将第一个操作数向右移动指定数量的位. 右边移出位被抛弃. 左边多出的空位由0补齐.19>>>2产生4,因为10011移位2位向右变为100,它是4。对非负数值,补零右移和带符号右移产生相同结果。
+ +

逻辑运算符

+ +

逻辑运算符常用于布尔(逻辑)值之间; 当操作数都是布尔值时,返回值也是布尔值。 不过实际上&&||返回的是一个特定的操作数的值,所以当它用于非布尔值的时候,返回值就可能是非布尔值。 逻辑运算符的描述如下。

+ +

逻辑运算符

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符范例描述
逻辑与 (&&)expr1 && expr2(逻辑与) 如果expr1能被转换为false,那么返回expr1;否则,返回expr2。因此,&&用于布尔值时,当操作数都为true时返回true;否则返回false.
逻辑或 (||)expr1 || expr2(逻辑或) 如果expr1能被转换为true,那么返回expr1;否则,返回expr2。因此,||用于布尔值时,当任何一个操作数为true则返回true;如果操作数都是false则返回false。
逻辑非 (!)!expr(逻辑非) 如果操作数能够转换为true则返回false;否则返回true。
+ +

能被转换为false的值有null, 0, NaN, 空字符串("")和undefined。(译者注:也可以称作”falsy“)

+ +

下面是&&(逻辑"与")操作符的示例。

+ +
var a1 =  true && true;     // t && t returns true
+var a2 =  true && false;    // t && f returns false
+var a3 = false && true;     // f && t returns false
+var a4 = false && (3 == 4); // f && f returns false
+var a5 = "Cat" && "Dog";    // t && t returns Dog
+var a6 = false && "Cat";    // f && t returns false
+var a7 = "Cat" && false;    // t && f returns false
+
+ +

下面是||(逻辑"或")操作符的示例。

+ +
var o1 =  true || true;     // t || t returns true
+var o2 = false || true;     // f || t returns true
+var o3 =  true || false;    // t || f returns true
+var o4 = false || (3 == 4); // f || f returns false
+var o5 = "Cat" || "Dog";    // t || t returns Cat
+var o6 = false || "Cat";    // f || t returns Cat
+var o7 = "Cat" || false;    // t || f returns Cat
+
+ +

下面是!(逻辑"非")操作符的示例。

+ +
var n1 = !true;  // !t returns false
+var n2 = !false; // !f returns true
+var n3 = !"Cat"; // !t returns false
+
+ +

短路求值

+ +

作为逻辑表达式进行求值是从左到右,它们是为可能的“短路”的出现而使用以下规则进行测试:

+ + + +

逻辑的规则,保证这些评估是总是正确的。请注意,上述表达式的anything部分不会被求值,所以这样做不会产生任何副作用。

+ +

字符串运算符

+ +

除了比较操作符,它可以在字符串值中使用,连接操作符(+)连接两个字符串值相连接,返回另一个字符串,它是两个操作数串的结合。

+ +

例如,

+ +
console.log("my " + "string"); // console logs the string "my string".
+ +

简写操作符 += 也可以用来拼接字符串,例如:

+ +
var myString = "alpha";
+
+myString += "bet"; // 返回 "alphabet"  
+
+ +

条件(三元)运算符

+ +

条件运算符是JavaScript中唯一需要三个操作数的运算符。运算的结果根据给定条件在两个值中取其一。语法为:

+ +
条件 ? 值1 : 值2
+
+ +

如果条件为真,则结果取值1。否则为值2。你能够在任何允许使用标准运算符的地方使用条件运算符。

+ +

例如,

+ +
var status = (age >= 18) ? "adult" : "minor";
+
+ +

age 大于等于18的时候,将“adult”赋值给 status;否则将“minor”赋值给 status

+ +

逗号操作符

+ +

逗号操作符,)对两个操作数进行求值并返回最终操作数的值。它常常用在 for 循环中,在每次循环时对多个变量进行更新。

+ +

例如,假如 a 是一个二维数组,每个维度各有10个元素,以下代码利用逗号操作符来同时改变两个变量的值。这段代码的功能是打印出该二维数组的对角线元素的值:

+ +
var x = [0,1,2,3,4,5,6,7,8,9]
+var a = [x, x, x, x, x];
+
+for (var i = 0, j = 9; i <= j; i++, j--)
+  console.log('a[' + i + '][' + j + ']= ' + a[i][j]);
+ +

一元操作符

+ +

一元操作符仅对应一个操作数。

+ +

delete

+ +

delete操作符,删除一个对象或一个对象的属性或者一个数组中某一个键值。语法如下:

+ +
delete objectName;
+delete objectName.property;
+delete objectName[index];
+delete property; // legal only within a with statement
+
+ +

objectName是一个对象名,property 是一个已经存在的属性,index是数组中的一个已经存在的键值的索引值。

+ +

第四行的形式只在with声明的状态下是合法的, 从对象中删除一个属性。

+ +

你能使用 delete 删除各种各样的隐式声明, 但是被var声明的除外。

+ +

如果 delete 操作成功,属性或者元素会变成 undefined。如果 delete可行会返回true,如果不成功返回false

+ +
x = 42;
+var y = 43;
+myobj = new Number();
+myobj.h = 4;    // create property h
+delete x;       // returns true (can delete if declared implicitly)
+delete y;       // returns false (cannot delete if declared with var)
+delete Math.PI; // returns false (cannot delete predefined properties)
+delete myobj.h; // returns true (can delete user-defined properties)
+delete myobj;   // returns true (can delete if declared implicitly)
+
+ +
删除数组元素
+ +

删除数组中的元素时,数组的长度是不变的,例如删除a[3], a[4]a[4]和a[3] 仍然存在变成了undefined

+ +

delete 删除数组中的一个元素,这个元素就不在数组中了。例如,trees[3]被删除,trees[3] 仍然可寻址并返回undefined

+ +
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
+delete trees[3];
+if (3 in trees) {
+  // 不会被执行
+}
+
+ +

如果想让数组中存在一个元素但是是undefined值,使用undefined关键字而不是delete操作. 如下: trees[3]分配一个undefined,但是这个数组元素仍然存在:

+ +
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
+trees[3] = undefined;
+if (3 in trees) {
+  // this gets executed(会被执行)
+}
+
+ +

typeof

+ +

typeof操作符 可通过下面2种方式使用:

+ +
typeof operand
+typeof (operand)
+
+ +

typeof 操作符返回一个表示 operand 类型的字符串值。operand 可为字符串、变量、关键词或对象,其类型将被返回。operand 两侧的括号为可选。

+ +

假设你定义了如下的变量:

+ +
var myFun = new Function("5 + 2");
+var shape = "round";
+var size = 1;
+var today = new Date();
+
+ +

typeof 操作符将会返回如下的结果:

+ +
typeof myFun;     // returns "function"
+typeof shape;     // returns "string"
+typeof size;      // returns "number"
+typeof today;     // returns "object"
+typeof dontExist; // returns "undefined"
+
+ +

对于关键词 true 和 null, typeof 操作符将会返回如下结果:

+ +
typeof true; // returns "boolean"
+typeof null; // returns "object"
+
+ +

对于一个数值或字符串, typeof 操作符将会返回如下结果:

+ +
typeof 62;            // returns "number"
+typeof 'Hello world'; // returns "string"
+
+ +

对于属性值,typeof 操作符将会返回属性所包含值的类型:

+ +
typeof document.lastModified; // returns "string"
+typeof window.length;         // returns "number"
+typeof Math.LN2;              // returns "number"
+
+ +

对于方法和函数,typeof 操作符将会返回如下结果:

+ +
typeof blur;        // returns "function"
+typeof eval;        // returns "function"
+typeof parseInt;    // returns "function"
+typeof shape.split; // returns "function"
+
+ +

对于预定义的对象,typeof 操作符将会返回如下结果:

+ +
typeof Date;     // returns "function"
+typeof Function; // returns "function"
+typeof Math;     // returns "object"
+typeof Option;   // returns "function"
+typeof String;   // returns "function"
+
+ +

void

+ +

void 运算符运用方法如下:

+ +
void (expression)
+void expression
+
+ +

void运算符,表明一个运算没有返回值。expression是javaScript表达式,括号中的表达式是一个可选项,当然使用该方式是一种好的形式。

+ +

你可以使用void运算符指明一个超文本链接。该表达式是有效的,但是并不会在当前文档中进行加载。

+ +

如下创建了一个超链接文本,当用户单击该文本时,不会有任何效果。

+ +
<a href="javascript:void(0)">Click here to do nothing</a>
+ +

下面的代码创建了一个超链接,当用户单击它时,提交一个表单。

+ +
<a href="javascript:void(document.form.submit())">
+Click here to submit</a>
+ +

关系操作符

+ +

关系操作符对操作数进行比较,根据比较结果真或假,返回相应的布尔值。

+ +

in

+ +

in操作符,如果所指定的属性确实存在于所指定的对象中,则会返回true,语法如下:

+ +
propNameOrNumber in objectName
+
+ +

在这里 propNameOrNumber可以是一个代表着属性名的字符串或者是一个代表着数组索引的数值表达式,而objectName则是一个对象名。

+ +

下面的例子是 in 操作的常见用法。

+ +
// Arrays
+var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
+0 in trees;        // returns true
+3 in trees;        // returns true
+6 in trees;        // returns false
+"bay" in trees;    // returns false (you must specify the index number,
+                   // not the value at that index)
+"length" in trees; // returns true (length is an Array property)
+
+// Predefined objects
+"PI" in Math;          // returns true
+var myString = new String("coral");
+"length" in myString;  // returns true
+
+// Custom objects
+var mycar = {make: "Honda", model: "Accord", year: 1998};
+"make" in mycar;  // returns true
+"model" in mycar; // returns true
+
+ +

instanceof

+ +

如果所判别的对象确实是所指定的类型,则返回true。其语法如下:

+ +
objectName instanceof objectType
+
+ +

objectName 是需要做判别的对象的名称,而objectType是假定的对象的类型, 例如{{jsxref("Date")}}或 {{jsxref("Array")}}.

+ +

当你需要确认一个对象在运行时的类型时,可使用instanceof. 例如,需要 catch 异常时,你可以针对抛出异常的类型,来做不同的异常处理。

+ +

例如, 下面的代码使用instanceof去判断 theDay是否是一个 Date 对象. 因为theDay是一个Date对象, 所以if中的代码会执行.

+ +
var theDay = new Date(1995, 12, 17);
+if (theDay instanceof Date) {
+  // statements to execute
+}
+
+ +

运算符优先级

+ +

运算符的优先级,用于确定一个表达式的计算顺序。在你不能确定优先级时,可以通过使用括号显式声明运算符的优先级。

+ +

下表列出了描述符的优先级,从最高到最低。

+ +

运算符优先级

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Operator typeIndividual operators
member. []
call / create instance() new
negation/increment! ~ - + ++ -- typeof void delete
multiply/divide* / %
addition/subtraction+ -
bitwise shift<< >> >>>
relational< <= > >= in instanceof
equality== != === !==
bitwise-and&
bitwise-xor^
bitwise-or|
logical-and&&
logical-or||
conditional?:
assignment= += -= *= /= %= <<= >>= >>>= &= ^= |=
comma,
+ +

上表有一个更详细的版本,它包含了各操作符更详细的说明,可在 JavaScript 参考手册 中找到。

+ +

表达式

+ +

表达式是一组代码的集合,它返回一个值。(译注:定义比较不好理解,看下面的举例就很好懂了。)

+ +

每一个合法的表达式都能计算成某个值,但从概念上讲,有两种类型的表达式:有副作用的(比如赋值)和单纯计算求值的。

+ +

表达式x=7是第一类型的一个例子。该表达式使用=运算符将值7赋予变量x。这个表达式自己的值等于7。

+ +

代码3 + 4是第二个表达式类型的一个例子。该表达式使用+运算符把3和4加到一起但并没有把结果(7)赋值给一个变量。

+ +

JavaScript有以下表达式类型:

+ + + +

基本表达式

+ +

this

+ +

this关键字被用于指代当前的对象,通常,this指代的是方法中正在被调用的对象。用法如下:

+ +
this["propertyName"]
+this.propertyName
+
+ +

假设一个用于验证对象value属性的validate函数,传参有对象,最高值和最低值。

+ +
function validate(obj, lowval, hival){
+  if ((obj.value < lowval) || (obj.value > hival))
+    console.log("Invalid Value!");
+}
+
+ +

你可以在任何表单元素的onchange事件处理中调用validat函数,用this来指代当前的表单元素,用例如下:

+ +
<p>Enter a number between 18 and 99:</p>
+<input type="text" name="age" size=3 onChange="validate(this, 18, 99);">
+
+ +

分组操作符

+ +

分组操作符()控制了表达式中计算的优先级. 举例来说, 你可以改变先乘除后加减的顺序,转而先计算加法。

+ +
var a = 1;
+var b = 2;
+var c = 3;
+
+// 默认优先级
+a + b * c     // 7
+// 默认是这样计算的
+a + (b * c)   // 7
+
+// 现在使加法优先于乘法
+(a + b) * c   // 9
+
+// 这等价于
+a * c + b * c // 9
+ +
数值推导
+ +

Comprehensions 是一个带有实验性质的JavaScript特性, 计划将在未来的ECMAScript版本中加入该特性. 有两种类型的comprehensions:

+ +
+
{{experimental_inline}} {{jsxref("Operators/Array_comprehensions", "[for (x of y) x]")}}
+
数列数值推导 (非标准用法)
+
{{experimental_inline}} {{jsxref("Operators/Generator_comprehensions", "(for (x of y) y)")}}
+
生成器数值推导 (译者注:生成器数值推导标准化可能不大,推荐使用 生成器函数
+
+ +

Comprehensions特性被许多编程语言所采用,该特性能够使你快速地通过一个已有的数组来创建出一个新的数组,比如:

+ +
[for (i of [ 1, 2, 3 ]) i*i ];
+// [ 1, 4, 9 ]
+
+var abc = [ "A", "B", "C" ];
+[for (letters of abc) letters.toLowerCase()];
+// [ "a", "b", "c" ]
+ +

左值表达式

+ +

左值可以作为赋值的目标。

+ +

new

+ +

你可以使用new operator 创建一个自定义类型或者是预置类型的对象实例。用法如下:

+ +
var objectName = new objectType([param1, param2, ..., paramN]);
+
+ +

super

+ +

super 关键字可以用来调用一个对象父类的函数,它在用来调用一个的父类的构造函数时非常有用,比如:

+ +
super([arguments]); // calls the parent constructor. super.functionOnParent([arguments]);
+ +

扩展语句

+ +

扩展语句符允许一个表达式在原地展开, 当需要多个参数 (比如函数调用时) 或者多个值(比如字面量数组) 。

+ +

例如:现在你有一个数组,你想创建一个新数组,并将刚才那个作为它的一部分,用array的字面语法是不够的,你不得不写一些代码实现它,比如用些pushspliceconcat等等。但是用spread syntax就没问题了:

+ +
var parts = ['shoulder', 'knees'];
+var lyrics = ['head', ...parts, 'and', 'toes'];
+ +

类似的,扩展语句也可以用在函数调用的时候:

+ +
function f(x, y, z) { }
+var args = [0, 1, 2];
+f(...args);
+ +
{{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}}
diff --git a/files/zh-cn/web/javascript/guide/functions/index.html b/files/zh-cn/web/javascript/guide/functions/index.html new file mode 100644 index 0000000000..bf26ec3c8e --- /dev/null +++ b/files/zh-cn/web/javascript/guide/functions/index.html @@ -0,0 +1,662 @@ +--- +title: 函数 +slug: Web/JavaScript/Guide/Functions +tags: + - JavaScript + - 函数 + - 初学者 + - 教程 +translation_of: Web/JavaScript/Guide/Functions +--- +

{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}

+ +

函数是 JavaScript 中的基本组件之一。 一个函数是 JavaScript 过程 — 一组执行任务或计算值的语句。要使用一个函数,你必须将其定义在你希望调用它的作用域内。

+ +

一个JavaScript 函数用function关键字定义,后面跟着函数名和圆括号。

+ +

查看 JavaScript 函数详细参考文档 了解更多。

+ +

定义函数

+ +

函数声明

+ +

一个函数定义(也称为函数声明,或函数语句)由一系列的function关键字组成,依次为:

+ + + +

例如,以下的代码定义了一个简单的square函数:

+ +
function square(number) {
+  return number * number;
+}
+
+ +

函数square使用了一个参数,叫作number。这个函数只有一个语句,它说明该函数将函数的参数(即number)自乘后返回。函数的return语句确定了函数的返回值:

+ +
return number * number;
+
+ +

原始参数(比如一个具体的数字)被作为传递给函数;值被传递给函数,如果被调用函数改变了这个参数的值,这样的改变不会影响到全局或调用函数。

+ +

如果你传递一个对象(即一个非原始值,例如{{jsxref("Array")}}或用户自定义的对象)作为参数,而函数改变了这个对象的属性,这样的改变对函数外部是可见的,如下面的例子所示:

+ +
function myFunc(theObject) {
+  theObject.make = "Toyota";
+}
+
+var mycar = {make: "Honda", model: "Accord", year: 1998};
+var x, y;
+
+x = mycar.make;     // x获取的值为 "Honda"
+
+myFunc(mycar);
+y = mycar.make;     // y获取的值为 "Toyota"
+                    // (make属性被函数改变了)
+
+ +

函数表达式

+ +

虽然上面的函数声明在语法上是一个语句,但函数也可以由函数表达式创建。这样的函数可以是匿名的;它不必有一个名称。例如,函数square也可这样来定义:

+ +
const square = function(number) { return number * number; };
+var x = square(4); // x gets the value 16
+ +

然而,函数表达式也可以提供函数名,并且可以用于在函数内部代指其本身,或者在调试器堆栈跟踪中识别该函数:

+ +
const factorial = function fac(n) {return n<2 ? 1 : n*fac(n-1)};
+
+console.log(factorial(3));
+
+ +

当将函数作为参数传递给另一个函数时,函数表达式很方便。下面的例子演示了一个叫map的函数如何被定义,而后使用一个表达式函数作为其第一个参数进行调用:

+ +
function map(f,a) {
+  let result = []; // 创建一个数组
+  let i; // 声明一个值,用来循环
+  for (i = 0; i != a.length; i++)
+    result[i] = f(a[i]);
+  return result;
+}
+
+ +

下面的代码:

+ +
function map(f, a) {
+  let result = []; // 创建一个数组
+  let i; // 声明一个值,用来循环
+  for (i = 0; i != a.length; i++)
+    result[i] = f(a[i]);
+  return result;
+}
+const f = function(x) {
+   return x * x * x;
+}
+let numbers = [0,1, 2, 5,10];
+let cube = map(f,numbers);
+console.log(cube);
+ +

返回 [0, 1, 8, 125, 1000]。

+ +

在 JavaScript 中,可以根据条件来定义一个函数。比如下面的代码,当num 等于 0 的时候才会定义 myFunc :

+ +
var myFunc;
+if (num == 0){
+  myFunc = function(theObject) {
+    theObject.make = "Toyota"
+  }
+}
+ +

除了上述的定义函数方法外,你也可以在运行时用 {{jsxref("Function")}} 构造器由一个字符串来创建一个函数 ,很像 {{jsxref("Global_Objects/eval", "eval()")}} 函数。

+ +

当一个函数是一个对象的属性时,称之为方法。了解更多关于对象和方法的知识 使用对象

+ +

调用函数

+ +

定义一个函数并不会自动的执行它。定义了函数仅仅是赋予函数以名称并明确函数被调用时该做些什么。调用函数才会以给定的参数真正执行这些动作。例如,一旦你定义了函数square,你可以如下这样调用它:

+ +
square(5);
+
+ +

上述语句通过提供参数 5 来调用函数。函数执行完它的语句会返回值25。

+ +

函数一定要处于调用它们的域中,但是函数的声明可以被提升(出现在调用语句之后),如下例:

+ +
console.log(square(5));
+/* ... */
+function square(n) { return n*n }
+
+ +

函数域是指函数声明时的所在的地方,或者函数在顶层被声明时指整个程序。

+ +
+

提示:注意只有使用如上的语法形式(即 function funcName(){})才可以。而下面的代码是无效的。就是说,函数提升仅适用于函数声明,而不适用于函数表达式。

+
+ +
console.log(square); // square is hoisted with an initial value undefined.
+console.log(square(5)); // Uncaught TypeError: square is not a function
+const square = function (n) {
+  return n * n;
+}
+ +

函数的参数并不局限于字符串或数字。你也可以将整个对象传递给函数。函数 show_props(其定义参见 用对象编程)就是一个将对象作为参数的例子。

+ +

函数可以被递归,就是说函数可以调用其本身。例如,下面这个函数就是用递归计算阶乘:

+ +
function factorial(n){
+  if ((n == 0) || (n == 1))
+    return 1;
+  else
+    return (n * factorial(n - 1));
+}
+
+ +

你可以计算1-5的阶乘如下:

+ +
var a, b, c, d, e;
+
+a = factorial(1); // 1赋值给a
+b = factorial(2); // 2赋值给b
+c = factorial(3); // 6赋值给c
+d = factorial(4); // 24赋值给d
+e = factorial(5); // 120赋值给e
+
+ +

还有其它的方式来调用函数。常见的一些情形是某些地方需要动态调用函数,或者函数的实参数量是变化的,或者调用函数的上下文需要指定为在运行时确定的特定对象。显然,函数本身就是对象,因此这些对象也有方法(参考{{jsxref("Function")}} )。作为此中情形之一,{{jsxref("Function.apply", "apply()")}}方法可以实现这些目的。

+ +

函数作用域

+ +

在函数内定义的变量不能在函数之外的任何地方访问,因为变量仅仅在该函数的域的内部有定义。相对应的,一个函数可以访问定义在其范围内的任何变量和函数。换言之,定义在全局域中的函数可以访问所有定义在全局域中的变量。在另一个函数中定义的函数也可以访问在其父函数中定义的所有变量和父函数有权访问的任何其他变量。

+ +
// 下面的变量定义在全局作用域(global scope)中
+var num1 = 20,
+    num2 = 3,
+    name = "Chamahk";
+
+// 本函数定义在全局作用域
+function multiply() {
+  return num1 * num2;
+}
+
+multiply(); // 返回 60
+
+// 嵌套函数的例子
+function getScore() {
+  var num1 = 2,
+      num2 = 3;
+
+  function add() {
+    return name + " scored " + (num1 + num2);
+  }
+
+  return add();
+}
+
+getScore(); // 返回 "Chamahk scored 5"
+
+ +

作用域和函数堆栈

+ +

递归

+ +

一个函数可以指向并调用自身。有三种方法可以达到这个目的:

+ +
    +
  1. 函数名
  2. +
  3. arguments.callee
  4. +
  5. 作用域下的一个指向该函数的变量名
  6. +
+ +

例如,思考一下如下的函数定义:

+ +
var foo = function bar() {
+   // statements go here
+};
+
+ +

在这个函数体内,以下的语句是等价的:

+ +
    +
  1. bar()
  2. +
  3. arguments.callee() (译者注:ES5禁止在严格模式下使用此属性)
  4. +
  5. foo()
  6. +
+ +

调用自身的函数我们称之为递归函数。在某种意义上说,递归近似于循环。两者都重复执行相同的代码,并且两者都需要一个终止条件(避免无限循环或者无限递归)。例如以下的循环:

+ +
var x = 0;
+while (x < 10) { // "x < 10" 是循环条件
+   // do stuff
+   x++;
+}
+
+ +

可以被转化成一个递归函数和对其的调用:

+ +
function loop(x) {
+  if (x >= 10) // "x >= 10" 是退出条件(等同于 "!(x < 10)")
+    return;
+  // 做些什么
+  loop(x + 1); // 递归调用
+}
+loop(0);
+
+ +

不过,有些算法并不能简单的用迭代来实现。例如,获取树结构中所有的节点时,使用递归实现要容易得多:

+ +
function walkTree(node) {
+  if (node == null) //
+    return;
+  // do something with node
+  for (var i = 0; i < node.childNodes.length; i++) {
+    walkTree(node.childNodes[i]);
+  }
+}
+
+ +

loop函数相比,这里每个递归调用都产生了更多的递归。

+ +

将递归算法转换为非递归算法是可能的,不过逻辑上通常会更加复杂,而且需要使用堆栈。事实上,递归函数就使用了堆栈:函数堆栈。

+ +

这种类似堆栈的行为可以在下例中看到:

+ +
function foo(i) {
+  if (i < 0)
+    return;
+  console.log('begin:' + i);
+  foo(i - 1);
+  console.log('end:' + i);
+}
+foo(3);
+
+// 输出:
+
+// begin:3
+// begin:2
+// begin:1
+// begin:0
+// end:0
+// end:1
+// end:2
+// end:3
+ +

嵌套函数和闭包

+ +

你可以在一个函数里面嵌套另外一个函数。嵌套(内部)函数对其容器(外部)函数是私有的。它自身也形成了一个闭包。一个闭包是一个可以自己拥有独立的环境与变量的表达式(通常是函数)。

+ +

既然嵌套函数是一个闭包,就意味着一个嵌套函数可以”继承“容器函数的参数和变量。换句话说,内部函数包含外部函数的作用域。

+ +

可以总结如下:

+ + + +

下面的例子展示了嵌套函数:

+ +
function addSquares(a, b) {
+  function square(x) {
+    return x * x;
+  }
+  return square(a) + square(b);
+}
+a = addSquares(2, 3); // returns 13
+b = addSquares(3, 4); // returns 25
+c = addSquares(4, 5); // returns 41
+ +

由于内部函数形成了闭包,因此你可以调用外部函数并为外部函数和内部函数指定参数:

+ +
function outside(x) {
+  function inside(y) {
+    return x + y;
+  }
+  return inside;
+}
+fn_inside = outside(3); // 可以这样想:给一个函数,使它的值加3
+result = fn_inside(5); // returns 8
+
+result1 = outside(3)(5); // returns 8
+ +

保存变量

+ +

注意到上例中 inside 被返回时 x 是怎么被保留下来的。一个闭包必须保存它可见作用域中所有参数和变量。因为每一次调用传入的参数都可能不同,每一次对外部函数的调用实际上重新创建了一遍这个闭包。只有当返回的 inside 没有再被引用时,内存才会被释放。

+ +

这与在其他对象中存储引用没什么不同,但是通常不太明显,因为并不能直接设置引用,也不能检查它们。

+ +

多层嵌套函数

+ +

函数可以被多层嵌套。例如,函数A可以包含函数B,函数B可以再包含函数C。B和C都形成了闭包,所以B可以访问A,C可以访问B和A。因此,闭包可以包含多个作用域;他们递归式的包含了所有包含它的函数作用域。这个称之为作用域链。(稍后会详细解释)

+ +

思考一下下面的例子:

+ +
function A(x) {
+  function B(y) {
+    function C(z) {
+      console.log(x + y + z);
+    }
+    C(3);
+  }
+  B(2);
+}
+A(1); // logs 6 (1 + 2 + 3)
+ +

在这个例子里面,C可以访问B的y和A的x。这是因为:

+ +
    +
  1. B形成了一个包含A的闭包,B可以访问A的参数和变量
  2. +
  3. C形成了一个包含B的闭包
  4. +
  5. B包含A,所以C也包含A,C可以访问B和A的参数和变量。换言之,C用这个顺序链接了B和A的作用域
  6. +
+ +

反过来却不是这样。A不能访问C,因为A看不到B中的参数和变量,C是B中的一个变量,所以C是B私有的。

+ +

命名冲突

+ +

当同一个闭包作用域下两个参数或者变量同名时,就会产生命名冲突。更近的作用域有更高的优先权,所以最近的优先级最高,最远的优先级最低。这就是作用域链。链的第一个元素就是最里面的作用域,最后一个元素便是最外层的作用域。

+ +

看以下的例子:

+ +
function outside() {
+  var x = 5;
+  function inside(x) {
+    return x * 2;
+  }
+  return inside;
+}
+
+outside()(10); // returns 20 instead of 10
+ +

命名冲突发生在return x上,inside的参数xoutside变量x发生了冲突。这里的作用链域是{insideoutside, 全局对象}。因此insidex具有最高优先权,返回了20(insidex)而不是10(outsidex)。

+ +

闭包

+ +

闭包是 JavaScript 中最强大的特性之一。JavaScript 允许函数嵌套,并且内部函数可以访问定义在外部函数中的所有变量和函数,以及外部函数能访问的所有变量和函数。

+ +

但是,外部函数却不能够访问定义在内部函数中的变量和函数。这给内部函数的变量提供了一定的安全性。

+ +

此外,由于内部函数可以访问外部函数的作用域,因此当内部函数生存周期大于外部函数时,外部函数中定义的变量和函数的生存周期将比内部函数执行时间长。当内部函数以某一种方式被任何一个外部函数作用域访问时,一个闭包就产生了。

+ +
var pet = function(name) {          //外部函数定义了一个变量"name"
+  var getName = function() {
+    //内部函数可以访问 外部函数定义的"name"
+    return name;
+  }
+  //返回这个内部函数,从而将其暴露在外部函数作用域
+  return getName;
+};
+myPet = pet("Vivie");
+
+myPet();                            // 返回结果 "Vivie"
+
+ +

实际上可能会比上面的代码复杂的多。在下面这种情形中,返回了一个包含可以操作外部函数的内部变量方法的对象。

+ +
var createPet = function(name) {
+  var sex;
+
+  return {
+    setName: function(newName) {
+      name = newName;
+    },
+
+    getName: function() {
+      return name;
+    },
+
+    getSex: function() {
+      return sex;
+    },
+
+    setSex: function(newSex) {
+      if(typeof newSex == "string"
+        && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
+        sex = newSex;
+      }
+    }
+  }
+}
+
+var pet = createPet("Vivie");
+pet.getName();                  // Vivie
+
+pet.setName("Oliver");
+pet.setSex("male");
+pet.getSex();                   // male
+pet.getName();                  // Oliver
+
+ +

在上面的代码中,外部函数的name变量对内嵌函数来说是可取得的,而除了通过内嵌函数本身,没有其它任何方法可以取得内嵌的变量。内嵌函数的内嵌变量就像内嵌函数的保险柜。它们会为内嵌函数保留“稳定”——而又安全——的数据参与运行。而这些内嵌函数甚至不会被分配给一个变量,或者不必一定要有名字。

+ +
var getCode = (function(){
+  var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...
+
+  return function () {
+    return secureCode;
+  };
+})();
+
+getCode();    // Returns the secret code
+
+ +
+

尽管有上述优点,使用闭包时仍然要小心避免一些陷阱。如果一个闭包的函数定义了一个和外部函数的某个变量名称相同的变量,那么这个闭包将无法引用外部函数的这个变量。

+ +
var createPet = function(name) {  // Outer function defines a variable called "name"
+  return {
+    setName: function(name) {    // Enclosed function also defines a variable called "name"
+      name = name;               // ??? How do we access the "name" defined by the outer function ???
+    }
+  }
+}
+
+
+ +

使用 arguments 对象

+ +

函数的实际参数会被保存在一个类似数组的arguments对象中。在函数内,你可以按如下方式找出传入的参数:

+ +
arguments[i]
+
+ +

其中i是参数的序数编号(译注:数组索引),以0开始。所以第一个传来的参数会是arguments[0]。参数的数量由arguments.length表示。

+ +

使用arguments对象,你可以处理比声明的更多的参数来调用函数。这在你事先不知道会需要将多少参数传递给函数时十分有用。你可以用arguments.length来获得实际传递给函数的参数的数量,然后用arguments对象来取得每个参数。

+ +

例如,设想有一个用来连接字符串的函数。唯一事先确定的参数是在连接后的字符串中用来分隔各个连接部分的字符(译注:比如例子里的分号“;”)。该函数定义如下:

+ +
function myConcat(separator) {
+   var result = ''; // 把值初始化成一个字符串,这样就可以用来保存字符串了!!
+   var i;
+   // iterate through arguments
+   for (i = 1; i < arguments.length; i++) {
+      result += arguments[i] + separator;
+   }
+   return result;
+}
+ +

你可以给这个函数传递任意数量的参数,它会将各个参数连接成一个字符串“列表”:

+ +
// returns "red, orange, blue, "
+myConcat(", ", "red", "orange", "blue");
+
+// returns "elephant; giraffe; lion; cheetah; "
+myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
+
+// returns "sage. basil. oregano. pepper. parsley. "
+myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
+
+ +
提示:arguments变量只是 类数组对象“,并不是一个数组。称其为类数组对象是说它有一个索引编号和length属性。尽管如此,它并不拥有全部的Array对象的操作方法。
+ +

更多信息请阅读JavaScript参考里的{{jsxref("Function")}}一文。

+ +

函数参数

+ +

从ECMAScript 6开始,有两个新的类型的参数:默认参数,剩余参数。

+ +

默认参数

+ +

在JavaScript中,函数参数的默认值是undefined。然而,在某些情况下设置不同的默认值是有用的。这时默认参数可以提供帮助。

+ +

在过去,用于设定默认参数的一般策略是在函数的主体中测试参数值是否为undefined,如果是则赋予这个参数一个默认值。如果在下面的例子中,调用函数时没有实参传递给b,那么它的值就是undefined,于是计算a*b得到、函数返回的是 NaN。但是,在下面的例子中,这个已经被第二行获取处理:

+ +
function multiply(a, b) {
+  b = (typeof b !== 'undefined') ?  b : 1;
+
+  return a*b;
+}
+
+multiply(5); // 5
+
+ +

使用默认参数,在函数体的检查就不再需要了。现在,你可以在函数头简单地把1设定为b的默认值:

+ +
function multiply(a, b = 1) {
+  return a*b;
+}
+
+multiply(5); // 5
+ +

了解更多默认参数的信息。

+ +

剩余参数

+ +

剩余参数语法允许将不确定数量的参数表示为数组。在下面的例子中,使用剩余参数收集从第二个到最后参数。然后,我们将这个数组的每一个数与第一个参数相乘。这个例子是使用了一个箭头函数,这将在下一节介绍。

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(x => multiplier * x);
+}
+
+var arr = multiply(2, 1, 2, 3);
+console.log(arr); // [2, 4, 6]
+ +

箭头函数

+ +

箭头函数表达式(也称胖箭头函数)相比函数表达式具有较短的语法并以词法的方式绑定 this。箭头函数总是匿名的。另见 hacks.mozilla.org 的博文:“深度了解ES6:箭头函数”。

+ +

有两个因素会影响引入箭头函数:更简洁的函数和 this

+ +

更简洁的函数

+ +

在一些函数模式中,更简洁的函数很受欢迎。对比一下:

+ +
var a = [
+  "Hydrogen",
+  "Helium",
+  "Lithium",
+  "Beryllium"
+];
+
+var a2 = a.map(function(s){ return s.length });
+
+console.log(a2); // logs [ 8, 6, 7, 9 ]
+
+var a3 = a.map( s => s.length );
+
+console.log(a3); // logs [ 8, 6, 7, 9 ]
+ +

this 的词法

+ +

在箭头函数出现之前,每一个新函数都重新定义了自己的 this 值(在构造函数中是一个新的对象;在严格模式下是未定义的;在作为“对象方法”调用的函数中指向这个对象;等等)。以面向对象的编程风格,这样着实有点恼人。

+ +
function Person() {
+  // 构造函数Person()将`this`定义为自身
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // 在非严格模式下,growUp()函数将`this`定义为“全局对象”,
+    // 这与Person()定义的`this`不同,
+    // 所以下面的语句不会起到预期的效果。
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

在ECMAScript 3/5里,通过把this的值赋值给一个变量可以修复这个问题。

+ +
function Person() {
+  var self = this; // 有的人习惯用`that`而不是`self`,
+                   // 无论你选择哪一种方式,请保持前后代码的一致性
+  self.age = 0;
+
+  setInterval(function growUp() {
+    // 以下语句可以实现预期的功能
+    self.age++;
+  }, 1000);
+}
+ +

另外,创建一个约束函数可以使得 this值被正确传递给 growUp() 函数。

+ +

箭头函数捕捉闭包上下文的this值,所以下面的代码工作正常。

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // 这里的`this`正确地指向person对象
+  }, 1000);
+}
+
+var p = new Person();
+ +

预定义函数

+ +

JavaScript语言有好些个顶级的内建函数:

+ +
+
{{jsxref("Global_Objects/eval", "eval()")}}
+
+

eval()方法会对一串字符串形式的JavaScript代码字符求值。

+
+
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
+
+

uneval()方法创建的一个{{jsxref("Object")}}的源代码的字符串表示。

+
+
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
+
+

isFinite()函数判断传入的值是否是有限的数值。 如果需要的话,其参数首先被转换为一个数值。

+
+
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
+
+

isNaN()函数判断一个值是否是{{jsxref("Global_Objects/NaN", "NaN")}}。注意:isNaN函数内部的强制转换规则十分有趣; 另一个可供选择的是ECMAScript 6 中定义{{jsxref("Number.isNaN()")}} , 或者使用 typeof来判断数值类型。

+
+
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
+
+

parseFloat() 函数解析字符串参数,并返回一个浮点数。

+
+
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
+
+

parseInt() 函数解析字符串参数,并返回指定的基数(基础数学中的数制)的整数。

+
+
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
+
+

decodeURI() 函数对先前经过{{jsxref("Global_Objects/encodeURI", "encodeURI")}}函数或者其他类似方法编码过的字符串进行解码。

+
+
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
+
+

decodeURIComponent()方法对先前经过{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}}函数或者其他类似方法编码过的字符串进行解码。

+
+
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
+
+

encodeURI()方法通过用以一个,两个,三个或四个转义序列表示字符的UTF-8编码替换统一资源标识符(URI)的某些字符来进行编码(每个字符对应四个转义序列,这四个序列组了两个”替代“字符)。

+
+
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
+
+

encodeURIComponent() 方法通过用以一个,两个,三个或四个转义序列表示字符的UTF-8编码替换统一资源标识符(URI)的每个字符来进行编码(每个字符对应四个转义序列,这四个序列组了两个”替代“字符)。

+
+
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
+
+

已废弃的 escape() 方法计算生成一个新的字符串,其中的某些字符已被替换为十六进制转义序列。使用 {{jsxref("Global_Objects/encodeURI", "encodeURI")}}或者{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}}替代本方法。

+
+
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
+
+

已废弃的 unescape() 方法计算生成一个新的字符串,其中的十六进制转义序列将被其表示的字符替换。上述的转义序列就像{{jsxref("Global_Objects/escape", "escape")}}里介绍的一样。因为 unescape 已经废弃,建议使用{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}或者{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} 替代本方法。

+
+
+ +
{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}
diff --git a/files/zh-cn/web/javascript/guide/grammar_and_types/index.html b/files/zh-cn/web/javascript/guide/grammar_and_types/index.html new file mode 100644 index 0000000000..0ea7538a96 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/grammar_and_types/index.html @@ -0,0 +1,705 @@ +--- +title: 语法和数据类型 +slug: Web/JavaScript/Guide/Grammar_and_types +tags: + - Enhanced Object Literals + - JavaScript + - 'Null' + - Object Literals + - Typed Objects + - typeof() + - 教程 +translation_of: Web/JavaScript/Guide/Grammar_and_types +--- +

{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

+ +

本章讨论 JavaScript 的基本语法,变量声明,数据类型 和 字面量。

+ +

基础

+ +

JavaScript 借鉴了 Java 的大部分语法,但同时也受到 Awk,Perl Python的影响。 

+ +

JavaScript 是区分大小写的,并使用 Unicode 字符集。举个例子,可以将单词 Früh (在德语中意思是“早”)用作变量名。

+ +
var Früh = "foobar";
+ +

但是,由于 JavaScript 是大小写敏感的,因此变量 früh 和 Früh 则是两个不同的变量。

+ +

在 JavaScript 中,指令被称为语句 ({{Glossary("Statement")}}),并用分号(;)进行分隔。

+ +

如果一条语句独占一行的话,那么分号是可以省略的。(译者注:并不建议这么做。)但如果一行中有多条语句,那么这些语句必须以分号分开。 ECMAScript 规定了在语句的末尾自动插入分号(ASI)。(如果想要了解更多信息,请参阅 JavaScript 词法语法 。)虽然不是必需的,但是在一条语句的末尾加上分号是一个很好的习惯。这个习惯可以大大减少代码中产生 bug 的可能性。

+ +

 Javascript 源码从左往右被扫描并转换成一系列由 token 、控制字符、行终止符、注释和空白字符组成的输入元素。空白字符指的是空格、制表符和换行符等。

+ +

注释

+ +

Javascript 注释的语法和 C++ 或许多其他语言类似:

+ +
// 单行注释
+
+/* 这是一个更长的,
+   多行注释
+*/
+
+/* 然而, 你不能, /* 嵌套注释 */ 语法错误 */
+ +

在代码执行过程中,注释将被自动跳过(不执行)。

+ +

声明

+ +

JavaScript有三种声明方式。

+ +
+
{{jsxref("Statements/var", "var")}}
+
声明一个变量,可选初始化一个值。
+
{{jsxref("Statements/let", "let")}}
+
声明一个块作用域的局部变量,可选初始化一个值。
+
{{jsxref("Statements/const", "const")}}
+
声明一个块作用域的只读常量。
+
+ +

变量

+ +

在应用程序中,使用变量来作为值的符号名。变量的名字又叫做{{Glossary("Identifier", "标识符")}},其需要遵守一定的规则。

+ +

一个 JavaScript 标识符必须以字母、下划线(_)或者美元符号($)开头;后续的字符也可以是数字(0-9)。因为 JavaScript 语言是区分大小写的,所以字母可以是从“A”到“Z”的大写字母和从“a”到“z”的小写字母。

+ +

你可以使用大部分 ISO 8859-1 或 Unicode 编码的字符作标识符,例如 å 和 ü(详情可查看这篇博客文章)。你也可以使用 Unicode 转义字符 作标识符。

+ +

合法的标识符示例:Number_hitstemp99$credit_name

+ +

声明变量

+ +

你可以用以下三种方式声明变量:

+ + + +

变量求值

+ +

varlet 语句声明的变量,如果没有赋初始值,则其值为 undefined

+ +

如果访问一个未声明的变量会导致抛出一个引用错误(ReferenceError)异常:

+ +
var a;
+console.log("The value of a is " + a); // a 的值是 undefined
+
+console.log("The value of b is " + b);// b 的值是 undefined
+var b;
+// 在你阅读下面的‘变量声明提升’前你可能会疑惑
+
+console.log("The value of c is " + c); // 未捕获的引用错误: c 未被定义
+
+let x;
+console.log("The value of x is " + x); // x 的值是 undefined
+
+console.log("The value of y is " + y);// 未捕获的引用错误: y 未被定义
+let y;
+ +

你可以使用 undefined 来判断一个变量是否已赋值。在以下的代码中,变量input未被赋值,因此 if 条件语句的求值结果是 true 。

+ +
var input;
+if(input === undefined){
+  doThis();
+} else {
+  doThat();
+}
+
+ +

The following is related to "Variables" section as potential values in assignment.undefined 值在布尔类型环境中会被当作 false 。例如,下面的代码将会执行函数 myFunction,因为数组 myArray 中的元素未被赋值:

+ +
var myArray = [];
+if (!myArray[0])   myFunction();
+
+ +

数值类型环境中 undefined 值会被转换为 NaN

+ +
var a;
+a + 2;    // 计算为 NaN
+
+ +

当你对一个 null 变量求值时,空值 null 在数值类型环境中会被当作0来对待,而布尔类型环境中会被当作 false。例如:

+ +
var n = null;
+console.log(n * 32); // 在控制台中会显示 0
+
+ +

变量的作用域

+ +

在函数之外声明的变量,叫做全局变量,因为它可被当前文档中的任何其他代码所访问。在函数内部声明的变量,叫做局部变量,因为它只能在当前函数的内部访问。

+ +

ECMAScript 6 之前的 JavaScript 没有 语句块 作用域;相反,语句块中声明的变量将成为语句块所在函数(或全局作用域)的局部变量。例如,如下的代码将在控制台输出 5,因为 x 的作用域是声明了 x 的那个函数(或全局范围),而不是 if 语句块。

+ +
if (true) {
+  var x = 5;
+}
+console.log(x); // 5
+
+ +

如果使用 ECMAScript 6 中的 let 声明,上述行为将发生变化。

+ +
if (true) {
+  let y = 5;
+}
+console.log(y); // ReferenceError: y 没有被声明
+ +

变量提升

+ +

JavaScript 变量的另一个不同寻常的地方是,你可以先使用变量稍后再声明变量而不会引发异常。这一概念称为变量提升;JavaScript 变量感觉上是被“提升”或移到了函数或语句的最前面。但是,提升后的变量将返回 undefined 值。因此在使用或引用某个变量之后进行声明和初始化操作,这个被提升的变量仍将返回 undefined 值。

+ +
/**
+ * 例子1
+ */
+console.log(x === undefined); // true
+var x = 3;
+
+
+/**
+ * 例子2
+ */
+// will return a value of undefined
+var myvar = "my value";
+
+(function() {
+  console.log(myvar); // undefined
+  var myvar = "local value";
+})();
+
+ +

上面的例子,也可写作:

+ +
/**
+ * 例子1
+ */
+var x;
+console.log(x === undefined); // true
+x = 3;
+
+/**
+ * 例子2
+ */
+var myvar = "my value";
+
+(function() {
+  var myvar;
+  console.log(myvar); // undefined
+  myvar = "local value";
+})();
+ +

由于存在变量提升,一个函数中所有的var语句应尽可能地放在接近函数顶部的地方。这个习惯将大大提升代码的清晰度。

+ +

在 ECMAScript 6 中,let(const)同样会被提升变量到代码块的顶部但是不会被赋予初始值。在变量声明之前引用这个变量,将抛出引用错误(ReferenceError)。这个变量将从代码块一开始的时候就处在一个“暂时性死区”,直到这个变量被声明为止。

+ +
console.log(x); // ReferenceError
+let x = 3;
+ +

函数提升

+ +

对于函数来说,只有函数声明会被提升到顶部,而函数表达式不会被提升。

+ +
/* 函数声明 */
+
+foo(); // "bar"
+
+function foo() {
+  console.log("bar");
+}
+
+
+/* 函数表达式 */
+
+baz(); // 类型错误:baz 不是一个函数
+
+var baz = function() {
+  console.log("bar2");
+};
+ +

全局变量

+ +

need links to pages discussing scope chains and the global object 实际上,全局变量是全局对象的属性。在网页中,(译注:缺省的)全局对象是 window ,所以你可以用形如 window.variable 的语法来设置和访问全局变量。

+ +

因此,你可以通过指定 window 或 frame 的名字,在当前 window 或 frame 访问另一个 window 或 frame 中声明的变量。例如,在文档里声明一个叫 phoneNumber 的变量,那么你就可以在子框架里使用 parent.phoneNumber 的方式来引用它。

+ +

常量(Constants)

+ +

你可以用关键字 const 创建一个只读的常量。常量标识符的命名规则和变量相同:必须以字母、下划线(_)或美元符号($)开头并可以包含有字母、数字或下划线。

+ +
const PI = 3.14;
+
+ +

常量不可以通过重新赋值改变其值,也不可以在代码运行时重新声明。它必须被初始化为某个值。

+ +

常量的作用域规则与 let 块级作用域变量相同。若省略const关键字,则该标识符将被视为变量。

+ +

在同一作用域中,不能使用与变量名或函数名相同的名字来命名常量。例如:

+ +
// 这会造成错误
+function f() {};
+const f = 5;
+
+// 这也会造成错误
+function f() {
+  const g = 5;
+  var g;
+
+  //语句
+}
+
+ +

然而,对象属性被赋值为常量是不受保护的,所以下面的语句执行时不会产生错误。

+ +
const MY_OBJECT = {"key": "value"};
+MY_OBJECT.key = "otherValue";
+ +

同样的,数组的被定义为常量也是不受保护的,所以下面的语句执行时也不会产生错误。

+ +
const MY_ARRAY = ['HTML','CSS'];
+MY_ARRAY.push('JAVASCRIPT');
+console.log(MY_ARRAY); //logs ['HTML','CSS','JAVASCRIPT'];
+
+ +

数据结构和类型

+ +

数据类型

+ +

最新的 ECMAScript 标准定义了8种数据类型:

+ + + +

虽然这些数据类型相对来说比较少,但是通过他们你可以在程序中开发有用的功能。对象(Objects)和函数(functions)是这门语言的另外两个基本元素。你可以把对象当作存放值的一个命名容器,然后将函数当作你的程序能够执行的步骤。

+ +

数据类型的转换

+ +

JavaScript是一种动态类型语言(dynamically typed language)。这意味着你在声明变量时可以不必指定数据类型,而数据类型会在代码执行时会根据需要自动转换。因此,你可以按照如下方式来定义变量:

+ +
var answer = 42;
+
+ +

然后,你还可以给同一个变量赋予一个字符串值,例如:

+ +
answer = "Thanks for all the fish...";
+ +

因为 JavaScript 是动态类型的,这种赋值方式并不会提示出错。

+ +

在包含的数字和字符串的表达式中使用加法运算符(+),JavaScript 会把数字转换成字符串。例如,观察以下语句:

+ +
x = "The answer is " + 42 // "The answer is 42"
+y = 42 + " is the answer" // "42 is the answer"
+
+ +

在涉及其它运算符(译注:如下面的减号'-')时,JavaScript语言不会把数字变为字符串。例如(译注:第一例是数学运算,第二例是字符串运算):

+ +
"37" - 7 // 30
+"37" + 7 // "377"
+
+ +

字符串转换为数字

+ +

有一些方法可以将内存中表示一个数字的字符串转换为对应的数字。

+ +

parseInt()parseFloat()

+ +

参见:parseInt()parseFloat()的相关页面。

+ +

 parseInt 方法只能返回整数,所以使用它会丢失小数部分。另外,调用 parseInt 时最好总是带上进制(radix) 参数,这个参数用于指定使用哪一种进制。

+ +

将字符串转换为数字的另一种方法是使用一元加法运算符

+ +
"1.1" + "1.1" = "1.11.1"
+(+"1.1") + (+"1.1") = 2.2
+// 注意:加入括号为清楚起见,不是必需的。
+
+ +

字面量 (Literals)

+ +

(译注:字面量是由语法表达式定义的常量;或,通过由一定字词组成的语词表达式定义的常量)

+ +

在JavaScript中,你可以使用各种字面量。这些字面量是脚本中按字面意思给出的固定的值,而不是变量。(译注:字面量是常量,其值是固定的,而且在程序脚本运行中不可更改,比如false,3.1415,thisIsStringOfHelloworld ,invokedFunction: myFunction("myArgument")。本节将介绍以下类型的字面量:

+ + + +

数组字面量 (Array literals)

+ +

数组字面值是一个封闭在方括号对([])中的包含有零个或多个表达式的列表,其中每个表达式代表数组的一个元素。当你使用数组字面值创建一个数组时,该数组将会以指定的值作为其元素进行初始化,而其长度被设定为元素的个数。

+ +

下面的示例用3个元素生成数组coffees,它的长度是3。

+ +
var coffees = ["French Roast", "Colombian", "Kona"];
+
+var a=[3];
+
+console.log(a.length); // 1
+
+console.log(a[0]); // 3
+ +
+

注意 这里的数组字面值也是一种对象初始化器。参考对象初始化器的使用

+
+ +

若在顶层(全局)脚本里用字面值创建数组,JavaScript语言将会在每次对包含该数组字面值的表达式求值时解释该数组。另一方面,在函数中使用的数组,将在每次调用函数时都会被创建一次。

+ +

数组字面值同时也是数组对象。有关数组对象的详情请参见数组对象一文。

+ +

数组字面值中的多余逗号

+ +

(译注:声明时)你不必列举数组字面值中的所有元素。若你在同一行中连写两个逗号(,),数组中就会产生一个没有被指定的元素,其初始值是undefined。以下示例创建了一个名为fish的数组:

+ +
var fish = ["Lion", , "Angel"];
+
+ +

在这个数组中,有两个已被赋值的元素,和一个空元素(fish[0]是"Lion",fish[1]是undefined,而fish[2]是"Angel";译注:此时数组的长度属性fish.length是3)。

+ +

如果你在元素列表的尾部添加了一个逗号,它将会被忽略。在下面的例子中,数组的长度是3,并不存在myList[3]这个元素(译注:这是指数组的第4个元素噢,作者是在帮大家复习数组元素的排序命名方法)。元素列表中其它所有的逗号都表示一个新元素(的开始)。

+ +
+

注意:尾部的逗号在早期版本的浏览器中会产生错误,因而编程时的最佳实践方式就是移除它们。

+
+ +

(译注:而“现代”的浏览器似乎鼓励这种方式,这也很好解释原因。尾部逗号可以减少向数组的最后添加元素时,因为忘记为这最后一个元素加逗号 所造成的错误。)

+ +
var myList = ['home', , 'school', ];
+
+ +

在下面的例子中,数组的长度是4,元素myList[0]myList[2]缺失(译注:没被赋值,因而是undefined)。

+ +
var myList = [ , 'home', , 'school'];
+
+ +

再看一个例子。在这里,该数组的长度是4,元素myList[1]myList[3]被漏掉了。(但是)只有最后的那个逗号被忽略。

+ +
var myList = ['home', , 'school', , ];
+
+ +

理解多余的逗号(在脚本运行时会被如何处理)的含义,对于从语言层面理解JavaScript是十分重要的。但是,在你自己写代码时:显式地将缺失的元素声明为undefined,将大大提高你的代码的清晰度和可维护性

+ +

布尔字面量 (Boolean literals)

+ +

(译注:即逻辑字面量)

+ +

布尔类型有两种字面量:truefalse

+ +

不要混淆作为布尔对象的真和假与布尔类型的原始值true和false。布尔对象是原始布尔数据类型的一个包装器。参见 布尔对象

+ +

整数 (Integers)

+ +

(译注:原文如此,没写成“整数字面量”,这里指的是整数字面量。)

+ +

整数可以用十进制(基数为10)、十六进制(基数为16)、八进制(基数为8)以及二进制(基数为2)表示。

+ + + +

严格模式下,八进制整数字面量必须以0o或0O开头,而不能以0开头。

+ +

整数字面量举例:

+ +
0, 117 and -345 (十进制, 基数为10)
+015, 0001 and -0o77 (八进制, 基数为8)
+0x1123, 0x00111 and -0xF1A7 (十六进制, 基数为16或"hex")
+0b11, 0b0011 and -0b11 (二进制, 基数为2)
+ +

浮点数字面量 (Floating-point literals)

+ +

浮点数字面值可以有以下的组成部分:

+ + + +

指数部分以“e”或“E”开头,后面跟着一个整数,可以有正负号(即前缀“+”或“-”)。浮点数字面量至少有一位数字,而且必须带小数点或者“e”(大写“E”也可)。

+ +

简言之,其语法是:

+ +
[(+|-)][digits][.digits][(E|e)[(+|-)]digits]
+ +

例如:

+ +
3.14
+-.2345789 // -0.23456789
+-3.12e+12  // -3.12*1012
+.1e-23    // 0.1*10-23=10-24=1e-24
+
+ +

对象字面量 (Object literals)

+ +

对象字面值是封闭在花括号对({})中的一个对象的零个或多个"属性名-值"对的(元素)列表。你不能在一条语句的开头就使用对象字面值,这将导致错误或产生超出预料的行为, 因为此时左花括号({)会被认为是一个语句块的起始符号。(译者:这 里需要对语句statement、块block等基本名词的解释)

+ +

以下是一个对象字面值的例子。对象car的第一个元素(译注:即一个属性/值对)定义了属性myCar;第二个元素,属性getCar,引用了一个函数(即CarTypes("Honda"));第三个元素,属性special,使用了一个已有的变量(即Sales)。

+ +
var Sales = "Toyota";
+
+function CarTypes(name) {
+  return (name === "Honda") ?
+    name :
+    "Sorry, we don't sell " + name + "." ;
+}
+
+var car = { myCar: "Saturn", getCar: CarTypes("Honda"), special: Sales };
+
+console.log(car.myCar);   // Saturn
+console.log(car.getCar);  // Honda
+console.log(car.special); // Toyota
+
+ +

更进一步的,你可以使用数字或字符串字面值作为属性的名字,或者在另一个字面值内嵌套上一个字面值。如下的示例中使用了这些可选项。

+ +
var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
+
+console.log(car.manyCars.b); // Jeep
+console.log(car[7]); // Mazda
+
+ +

对象属性名字可以是任意字符串,包括空串。如果对象属性名字不是合法的javascript标识符,它必须用""包裹。属性的名字不合法,那么便不能用.访问属性值,而是通过类数组标记("[]")访问和赋值。

+ +
var unusualPropertyNames = {
+  "": "An empty string",
+  "!": "Bang!"
+}
+console.log(unusualPropertyNames."");   // 语法错误: Unexpected string
+console.log(unusualPropertyNames[""]);  // An empty string
+console.log(unusualPropertyNames.!);    // 语法错误: Unexpected token !
+console.log(unusualPropertyNames["!"]); // Bang!
+ +

增强的对象字面量 (Enhanced Object literals)

+ +

在ES2015,对象字面值扩展支持在创建时设置原型,简写了 foo: foo 形式的属性赋值,方法定义,支持父方法调用,以及使用表达式动态计算属性名。总之,这些也使对象字面值和类声明更加紧密地联系起来,让基于对象的设计从这些便利中更加受益。

+ +
var obj = {
+    // __proto__
+    __proto__: theProtoObj,
+    // Shorthand for ‘handler: handler’
+    handler,
+    // Methods
+    toString() {
+     // Super calls
+     return "d " + super.toString();
+    },
+    // Computed (dynamic) property names
+    [ 'prop_' + (() => 42)() ]: 42
+};
+ +

请注意:

+ +
var foo = {a: "alpha", 2: "two"};
+console.log(foo.a);    // alpha
+console.log(foo[2]);   // two
+//console.log(foo.2);  // SyntaxError: missing ) after argument list
+//console.log(foo[a]); // ReferenceError: a is not defined
+console.log(foo["a"]); // alpha
+console.log(foo["2"]); // two
+ +

RegExp 字面值

+ +

一个正则表达式是字符被斜线(译注:正斜杠“/”)围成的表达式。下面是一个正则表达式文字的一个例子。

+ +
var re = /ab+c/;
+ +

字符串字面量 (String literals)

+ +

字符串字面量是由双引号(")对或单引号(')括起来的零个或多个字符。字符串被限定在同种引号之间;也即,必须是成对单引号或成对双引号。下面的例子都是字符串字面值:

+ +
"foo"
+'bar'
+"1234"
+"one line \n another line"
+"John's cat"
+ +

你可以在字符串字面值上使用字符串对象的所有方法——JavaScript会自动将字符串字面值转换为一个临时字符串对象,调用该方法,然后废弃掉那个临时的字符串对象。你也能用对字符串字面值使用类似String.length的属性:

+ +
console.log("John's cat".length)
+// 将打印字符串中的字符个数(包括空格)
+// 结果为:10
+ +

在ES2015中,还提供了一种模板字面量(template literals),模板字符串提供了一些语法糖来帮你构造字符串。这与Perl、Python还有其他语言中的字符串插值(string interpolation)的特性非常相似。除此之外,你可以在通过模板字符串前添加一个tag来自定义模板字符串的解析过程,这可以用来防止注入攻击,或者用来建立基于字符串的高级数据抽象。

+ +
// Basic literal string creation
+`In JavaScript '\n' is a line-feed.`
+
+// Multiline strings
+`In JavaScript this is
+ not legal.`
+
+// String interpolation
+var name = "Bob", time = "today";
+`Hello ${name}, how are you ${time}?`
+
+// Construct an HTTP request prefix is used to interpret the replacements and construction
+POST`http://foo.org/bar?a=${a}&b=${b}
+     Content-Type: application/json
+     X-Credentials: ${credentials}
+     { "foo": ${foo},
+       "bar": ${bar}}`(myOnReadyStateChangeHandler);
+
+ +

除非有特别需要使用字符串对象,否则,你应当始终使用字符串字面值。要查看字符串对象的有关细节,请参见字符串对象

+ +

在字符串中使用的特殊字符

+ +

作为一般字符的扩展,你可以在字符串中使用特殊字符,如下例所示。

+ +
"one line \n another line"
+
+ +

以下表格列举了你能在JavaScript的字符串中使用的特殊字符。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
表 2.1 JavaScript 特殊字符
字符意思
\0Null字节
\b退格符
\f换页符
\n换行符
\r回车符
\tTab (制表符)
\v垂直制表符
\'单引号
\"双引号
\\反斜杠字符(\)
\XXX由从0到377最多三位八进制数XXX表示的 Latin-1 字符。例如,\251是版权符号的八进制序列。
\xXX由从00和FF的两位十六进制数字XX表示的Latin-1字符。例如,\ xA9是版权符号的十六进制序列。
\uXXXX由四位十六进制数字XXXX表示的Unicode字符。例如,\ u00A9是版权符号的Unicode序列。见Unicode escape sequences (Unicode 转义字符).
\u{XXXXX}Unicode代码点 (code point) 转义字符。例如,\u{2F804} 相当于Unicode转义字符 \uD87E\uDC04的简写。
+ +

译注:严格模式下,不能使用八进制转义字符。

+ +

转义字符

+ +

对于那些未出现在表2.1中的字符,其所带的前导反斜线'\'将被忽略。但是,这一用法已被废弃,应当避免使用。

+ +

通过在引号前加上反斜线'\',可以在字符串中插入引号,这就是引号转义。例如:

+ +
var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
+console.log(quote);
+
+ +

代码的运行结果为:

+ +
He read "The Cremation of Sam McGee" by R.W. Service.
+
+ +

要在字符串中插入'\'字面值,必须转义反斜线。例如,要把文件路径 c:\temp 赋值给一个字符串,可以采用如下方式:

+ +
var home = "c:\\temp";
+
+ +

也可以在换行之前加上反斜线以转义换行(译注:实际上就是一条语句拆成多行书写),这样反斜线和换行都不会出现在字符串的值中。

+ +
var str = "this string \
+is broken \
+across multiple\
+lines."
+console.log(str);   // this string is broken across multiplelines.
+
+ +

Javascript没有“heredoc”语法,但可以用行末的换行符转义和转义的换行来近似实现 

+ +
var poem =
+"Roses are red,\n\
+Violets are blue.\n\
+Sugar is sweet,\n\
+and so is foo."
+
+ +

ECMAScript 2015 增加了一种新的字面量,叫做模板字面量 template literals它包含一些新特征,包括了多行字符串!

+ +
var poem =
+`Roses are red,
+Violets are blue.
+Sugar is sweet,
+and so is foo.`
+ +

更多信息

+ +

?本章重点包括声明和类型的基本语法。学习更多关于的JavaScript语言,可参见本站以下章节:

+ + + +

下一章,流程控制与错误处理

+ +

{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

diff --git a/files/zh-cn/web/javascript/guide/index.html b/files/zh-cn/web/javascript/guide/index.html new file mode 100644 index 0000000000..d1ae6683bd --- /dev/null +++ b/files/zh-cn/web/javascript/guide/index.html @@ -0,0 +1,135 @@ +--- +title: JavaScript 指南 +slug: Web/JavaScript/Guide +tags: + - Guide + - JavaScript +translation_of: Web/JavaScript/Guide +--- +
{{jsSidebar("JavaScript Guide")}}
+ +

JavaScript 指南向你介绍如何使用 JavaScript,并且给出了语言概述。如果你需要了解某些语言特性的详细信息,请参阅 JavaScript 参考

+ +

章节

+ +

本指南分为以下章节:

+ + + + + + + + + +

{{Next("Web/JavaScript/Guide/Introduction")}}

diff --git a/files/zh-cn/web/javascript/guide/indexed_collections/index.html b/files/zh-cn/web/javascript/guide/indexed_collections/index.html new file mode 100644 index 0000000000..5dddf74d46 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/indexed_collections/index.html @@ -0,0 +1,478 @@ +--- +title: 索引集合类 (Indexed collections) +slug: Web/JavaScript/Guide/Indexed_collections +translation_of: Web/JavaScript/Guide/Indexed_collections +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Keyed_Collections")}}
+ +

这个章节主要介绍了以索引进行排序的数据集合。包括数组以及类似于数组的数据结构,如 {{jsxref("Array")}} {{jsxref("TypedArray")}} 

+ +

数组对象(Array object)

+ +

数组(array)是一个有序的数据集合,我们可以通过数组名称(name)和索引(index)进行访问。例如,我们定义了一个数组emp,数组中的每个元素包含了一个雇员的名字以及其作为索引的员工号。那么emp[1]将会代表1号员工,emp[2]将会代表2号员工,以此类推。

+ +

JavaScript中没有明确的数组数据类型。但是,我们可以通过使用内置Array对象和它的方法对数组进行操作。Array对象有很多操作数组的方法,比如合并、反转、排序等。数组对象有一个决定数组长度和使用正则表达式操作其他属性的属性。

+ +

创建数组(creating an array)

+ +

以下语句创建等效的数组:

+ +
var arr = new Array(element0, element1, ..., elementN);
+var arr = Array(element0, element1, ..., elementN);
+var arr = [element0, element1, ..., elementN];
+
+// 译者注: var arr=[4] 和 var arr=new Array(4)是不等效的,
+// 后者4指数组长度,所以使用字面值(literal)的方式应该不仅仅是便捷,同时也不易踩坑
+ +

element0, element1, ..., elementN 是数组元素的值的列表。当这些值被指定后,数组将被初始化,他们将被作为数组元素。数组的length属性也会被设为参数的个数。

+ +

括号语法被称为 "数组字面值" 或 "数组初始化器", 它比其他创建数组的方式更便捷,所以通常是首选。详细内容参见 Array literals 。

+ +

为了创建一个长度不为0,但是又没有任何元素的数组,可选以下任何一种方式:

+ +
var arr = new Array(arrayLength);
+var arr = Array(arrayLength);
+
+// 这样有同样的效果
+var arr = [];
+arr.length = arrayLength;
+
+ +
+

注意: 以上代码,数组长度(arrayLength)必须为一个数字(Number)。否则,将会创建一个只有单个(所输入的)元素的数组。 调用 arr.length 会返回数组长度,但是数组实际上包含了空的(undefined)元素。 因此在数组上使用 for...in 循环,将不会返回任何的值 。

+
+ +

除了如上所示创建新定义的变量,数组(array)也可以作为一个属性(property)分配给一个新的或者已存在的对象(object):

+ +
var obj = {};
+// ...
+obj.prop = [element0, element1, ..., elementN];
+
+// OR
+var obj = {prop: [element0, element1, ...., elementN]}
+
+ +

如果你希望用单个元素初始化一个数组,而这个元素恰好又是数字(Number),那么你必须使用括号语法。当单个的数字(Number)传递给Array()构造函数时,将会被解释为数组长度,并非单个元素。

+ +
var arr = [42];      // 创建一个只有唯一元素的数组:
+                     // the number 42.
+var arr = Array(42); // 创建一个没有元素的数组,
+                     // 但是数组的长度被设置成42.
+
+// 上面的代码与下面的代码等价
+var arr = [];
+arr.length = 42;
+
+ +

如果N不是一个整数,调用Array(N)将会报RangeError错误, 以下方法说明了这种行为:

+ +
var arr = Array(9.3);  // RangeError: Invalid array length
+
+ +

如果你需要创建任意类型的单元素数组,安全的方式是使用字面值。或者在向数组添加单个元素之前先创建一个空的数组。

+ +

填充数组(populating an array)

+ +

你可以通过给元素赋值来填充数组,例如:

+ +
var emp = [];
+emp[0] = "Casey Jones";
+emp[1] = "Phil Lesh";
+emp[2] = "August West";
+
+ +
+

注意:如果你在以上代码中给数组操作符的是一个非整形数值,那么将作为一个代表数组的对象的属性(property)创建,而非作为数组的元素。

+
+ +
var arr = [];
+arr[3.4] = "Oranges";
+console.log(arr.length);                // 0
+console.log(arr.hasOwnProperty(3.4));   // true
+
+ +

你也可以在创建数组的时候去填充它:

+ +
var myArray = new Array("Hello", myVar, 3.14159);
+var myArray = ["Mango", "Apple", "Orange"]
+
+ +

引用数组元素(referring to array elements)

+ +

您通过可以使用元素的序号来引用数组的元素。例如,假设你定义了如下数组:

+ +
var myArray = ["Wind", "Rain", "Fire"];
+
+ +

你可以用 myArray[0]引用第一个元素,myArray[1]引用第二个元素。元素的索引是从0开始的。

+ +
+

注意:数组操作符(方括号 [ ])也可以用来访问数组的属性(在 JavaScript 中,数组也是对象)。例如:

+
+ +
var arr = ["one", "two", "three"];
+arr[2];  // three
+arr["length"];  // 3
+
+ +

理解 length

+ +

在实施层面, JavaScript实际上是将元素作为标准的对象属性来存储,把数组索引作为属性名。长度属性是特殊的,它总是返回最后一个元素的索引值加1(下例中, Dusty 的索引是30,所以cats.length 返回 30 + 1)。记住, JavaScript 数组索引是基于0的: 他们从0开始,而不是1。这意味着数组长度属性将比最大的索引值大1:

+ +
var cats = [];
+cats[30] = ['Dusty'];
+console.log(cats.length); // 31
+
+ +

你也可以分配length属性。写一个小于数组元素数量的值会缩短数组,写0会彻底清空数组:

+ +
var cats = ['Dusty', 'Misty', 'Twiggy'];
+console.log(cats.length); // 3
+
+cats.length = 2;
+console.log(cats); // logs "Dusty,Misty" - Twiggy has been removed
+
+cats.length = 0;
+console.log(cats); // logs nothing; the cats array is empty
+
+cats.length = 3;
+console.log(cats); // [undefined, undefined, undefined]
+
+ +

遍历数组(interating over array)

+ +

遍历数组元素并以某种方式处理每个元素是一个常见的操作。以下是最简单的方式:

+ +
var colors = ['red', 'green', 'blue'];
+for (var i = 0; i < colors.length; i++) {
+  console.log(colors[i]);
+}
+
+ +

如果你确定数组中没有一个元素的求值是false —— 如果你的数组只包含DOM节点,如下,你可以选择一个更高效的土法子:

+ +
var divs = document.getElementsByTagName('div');
+for (var i = 0, div; div = divs[i]; i++) {
+  /* Process div in some way */
+}
+
+ +

这样避免了检测数组长度的开销,额外的好处是确保了div变量当前在每次循环中都被重新赋值为当前项。

+ +

{{jsxref("Array.forEach", "forEach()")}} 方法提供了遍历数组元素的其他方法:

+ +
var colors = ['red', 'green', 'blue'];
+colors.forEach(function(color) {
+  console.log(color);
+});
+
+ +

被传递给forEach的函数会在数组的每个元素像上执行一次,元素作为参数传递给该函数。未赋值的值不会在forEach循环迭代。

+ +

注意,在数组定义时省略的元素不会在forEach遍历时被列出,但是手动赋值为undefined的元素是会被列出的:

+ +
var array = ['first', 'second', , 'fourth'];
+
+// returns ['first', 'second', 'fourth'];
+array.forEach(function(element) {
+  console.log(element);
+})
+
+if(array[2] === undefined) { console.log('array[2] is undefined'); } // true
+
+var array = ['first', 'second', undefined, 'fourth'];
+
+// returns ['first', 'second', undefined, 'fourth'];
+array.forEach(function(element) {
+  console.log(element);
+})
+ +

一旦 JavaScript 元素被保存为标准的对象属性,通过for...in 循环来迭代数组将变得不明智,因为正常元素和所有可枚举的属性都会被列出。

+ +

数组的方法(array methods)

+ +

{{jsxref("Array")}} 对象具有下列方法:

+ +

{{jsxref("Array.concat", "concat()")}} 连接两个数组并返回一个新的数组。

+ +
var myArray = new Array("1", "2", "3");
+myArray = myArray.concat("a", "b", "c");
+// myArray is now ["1", "2", "3", "a", "b", "c"]
+
+ +

{{jsxref("Array.join", "join(deliminator = ',')")}} 将数组的所有元素连接成一个字符串。

+ +
var myArray = new Array("Wind", "Rain", "Fire");
+var list = myArray.join(" - "); // list is "Wind - Rain - Fire"
+
+ +

{{jsxref("Array.push", "push()")}} 在数组末尾添加一个或多个元素,并返回数组操作后的长度。

+ +
var myArray = new Array("1", "2");
+myArray.push("3"); // myArray is now ["1", "2", "3"]
+
+ +

{{jsxref("Array.pop", "pop()")}} 从数组移出最后一个元素,并返回该元素。

+ +
var myArray = new Array("1", "2", "3");
+var last = myArray.pop();
+// myArray is now ["1", "2"], last = "3"
+
+ +

{{jsxref("Array.shift", "shift()")}} 从数组移出第一个元素,并返回该元素。

+ +
var myArray = new Array ("1", "2", "3");
+var first = myArray.shift();
+// myArray is now ["2", "3"], first is "1"
+
+ +

{{jsxref("Array.shift", "unshift()")}} 在数组开头添加一个或多个元素,并返回数组的新长度。

+ +
var myArray = new Array ("1", "2", "3");
+myArray.unshift("4", "5");
+// myArray becomes ["4", "5", "1", "2", "3"]
+ +

{{jsxref("Array.slice", "slice(start_index, upto_index)")}} 从数组提取一个片段,并作为一个新数组返回。

+ +
var myArray = new Array ("a", "b", "c", "d", "e");
+myArray = myArray.slice(1, 4); // 包含索引1,不包括索引4
+                               // returning [ "b", "c", "d"]
+
+ +

{{jsxref("Array.splice", "splice(index, count_to_remove, addElement1, addElement2, ...)")}}从数组移出一些元素,(可选)并替换它们。

+ +
var myArray = new Array ("1", "2", "3", "4", "5");
+myArray.splice(1, 3, "a", "b", "c", "d");
+// myArray is now ["1", "a", "b", "c", "d", "5"]
+// This code started at index one (or where the "2" was),
+// removed 3 elements there, and then inserted all consecutive
+// elements in its place.
+
+ +

{{jsxref("Array.reverse", "reverse()")}} 颠倒数组元素的顺序:第一个变成最后一个,最后一个变成第一个。

+ +
var myArray = new Array ("1", "2", "3");
+myArray.reverse();
+// transposes the array so that myArray = [ "3", "2", "1" ]
+
+ +

{{jsxref("Array.sort", "sort()")}} 给数组元素排序。

+ +
var myArray = new Array("Wind", "Rain", "Fire");
+myArray.sort();
+// sorts the array so that myArray = [ "Fire", "Rain", "Wind" ]
+
+ +

sort() 也可以带一个回调函数来决定怎么比较数组元素。这个回调函数比较两个值,并返回3个值中的一个:

+ +

例如,下面的代码通过字符串的最后一个字母进行排序:

+ +
var sortFn = function(a, b){
+  if (a[a.length - 1] < b[b.length - 1]) return -1;
+  if (a[a.length - 1] > b[b.length - 1]) return 1;
+  if (a[a.length - 1] == b[b.length - 1]) return 0;
+}
+myArray.sort(sortFn);
+// sorts the array so that myArray = ["Wind","Fire","Rain"]
+ + + +

{{jsxref("Array.indexOf", "indexOf(searchElement[, fromIndex])")}} 在数组中搜索searchElement 并返回第一个匹配的索引。

+ +
var a = ['a', 'b', 'a', 'b', 'a'];
+console.log(a.indexOf('b')); // logs 1
+// Now try again, starting from after the last match
+console.log(a.indexOf('b', 2)); // logs 3
+console.log(a.indexOf('z')); // logs -1, because 'z' was not found
+
+ +

{{jsxref("Array.lastIndexOf", "lastIndexOf(searchElement[, fromIndex])")}} 和 indexOf 差不多,但这是从结尾开始,并且是反向搜索。

+ +
var a = ['a', 'b', 'c', 'd', 'a', 'b'];
+console.log(a.lastIndexOf('b')); // logs 5
+// Now try again, starting from before the last match
+console.log(a.lastIndexOf('b', 4)); // logs 1
+console.log(a.lastIndexOf('z')); // logs -1
+
+ +

{{jsxref("Array.forEach", "forEach(callback[, thisObject])")}} 在数组每个元素项上执行callback

+ +
var a = ['a', 'b', 'c'];
+a.forEach(function(element) { console.log(element);} );
+// logs each item in turn
+
+ +

{{jsxref("Array.map", "map(callback[, thisObject])")}} 在数组的每个单元项上执行callback函数,并把返回包含回调函数返回值的新数组(译者注:也就是遍历数组,并通过callback对数组元素进行操作,并将所有操作结果放入数组中并返回该数组)。

+ +
var a1 = ['a', 'b', 'c'];
+var a2 = a1.map(function(item) { return item.toUpperCase(); });
+console.log(a2); // logs A,B,C
+
+ +

{{jsxref("Array.filter", "filter(callback[, thisObject])")}} 返回一个包含所有在回调函数上返回为true的元素的新数组(译者注:callback在这里担任的是过滤器的角色,当元素符合条件,过滤器就返回true,而filter则会返回所有符合过滤条件的元素)。

+ +
var a1 = ['a', 10, 'b', 20, 'c', 30];
+var a2 = a1.filter(function(item) { return typeof item == 'number'; });
+console.log(a2); // logs 10,20,30
+
+ +

{{jsxref("Array.every", "every(callback[, thisObject])")}} 当数组中每一个元素在callback上被返回true时就返回true(译者注:同上,every其实类似filter,只不过它的功能是判断是不是数组中的所有元素都符合条件,并且返回的是布尔值)。

+ +
function isNumber(value){
+  return typeof value == 'number';
+}
+var a1 = [1, 2, 3];
+console.log(a1.every(isNumber)); // logs true
+var a2 = [1, '2', 3];
+console.log(a2.every(isNumber)); // logs false
+
+ +

{{jsxref("Array.some", "some(callback[, thisObject])")}} 只要数组中有一项在callback上被返回true,就返回true(译者注:同上,类似every,不过前者要求都符合筛选条件才返回true,后者只要有符合条件的就返回true)。

+ +
function isNumber(value){
+  return typeof value == 'number';
+}
+var a1 = [1, 2, 3];
+console.log(a1.some(isNumber)); // logs true
+var a2 = [1, '2', 3];
+console.log(a2.some(isNumber)); // logs true
+var a3 = ['1', '2', '3'];
+console.log(a3.some(isNumber)); // logs false
+
+ +

以上方法都带一个被称为迭代方法的的回调函数,因为他们以某种方式迭代整个数组。都有一个可选的第二参数 thisObject,如果提供了这个参数,thisObject 变成回调函数内部的 this 关键字的值。如果没有提供,例如函数在一个显示的对象上下文外被调用时,this 将引用全局对象({{domxref("window")}}).

+ +

实际上在调用回调函数时传入了3个参数。第一个是当前元素项的值,第二个是它在数组中的索引,第三个是数组本身的一个引用。 JavaScript 函数忽略任何没有在参数列表中命名的参数,因此提供一个只有一个参数的回调函数是安全的,例如 alert

+ +

{{jsxref("Array.reduce", "reduce(callback[, initialValue])")}} 使用回调函数 callback(firstValue, secondValue) 把数组列表计算成一个单一值(译者注:他数组元素两两递归处理的方式把数组计算成一个值)

+ +
var a = [10, 20, 30];
+var total = a.reduce(function(first, second) { return first + second; }, 0);
+console.log(total) // Prints 60
+
+ +

{{jsxref("Array.reduceRight", "reduceRight(callback[, initalvalue])")}} 和 reduce()相似,但这从最后一个元素开始的。

+ +

reducereduceRight 是迭代数组方法中最不被人熟知的两个函数.。他们应该使用在那些需要把数组的元素两两递归处理,并最终计算成一个单一结果的算法。

+ +

多维数组(multi-dimensional arrays)

+ +

数组是可以嵌套的, 这就意味着一个数组可以作为一个元素被包含在另外一个数组里面。利用JavaScript数组的这个特性, 可以创建多维数组。

+ +

以下代码创建了一个二维数组。

+ +
var a = new Array(4);
+for (i = 0; i < 4; i++) {
+  a[i] = new Array(4);
+  for (j = 0; j < 4; j++) {
+    a[i][j] = "[" + i + "," + j + "]";
+  }
+}
+
+ +

这个例子创建的数组拥有以下行数据:

+ +
Row 0: [0,0] [0,1] [0,2] [0,3]
+Row 1: [1,0] [1,1] [1,2] [1,3]
+Row 2: [2,0] [2,1] [2,2] [2,3]
+Row 3: [3,0] [3,1] [3,2] [3,3]
+
+ +

数组和正则表达式

+ +

当一个数组作为字符串和正则表达式的匹配结果时,该数组将会返回相关匹配信息的属性和元素。 RegExp.exec(), String.match() 和 String.split() 的返回值是一个数组。 使用数组和正则表达式的的更多信息, 请看 Regular Expressions.

+ +

使用类数组对象(array-like objects)

+ +

一些 JavaScript 对象, 例如 {{domxref("document.getElementsByTagName()")}} 返回的 {{domxref("NodeList")}} 或者函数内部可用的 arguments 对象,他们表面上看起来,外观和行为像数组,但是不共享他们所有的方法。例如 arguments 对象就提供一个 length 属性,但是不实现 {{jsxref("Array.forEach", "forEach()")}} 方法。

+ +

Array的原生(prototype)方法可以用来处理类似数组行为的对象,例如: :

+ +
function printArguments() {
+  Array.prototype.forEach.call(arguments, function(item) {
+    console.log(item);
+  });
+}
+ +

Array的常规方法也可以用于处理字符串,因为它提供了序列访问字符转为数组的简单方法:

+ +
Array.prototype.forEach.call("a string", function(chr) {
+  console.log(chr);
+});
+ +

数组推导式(Array comprehensions)

+ +

JavaScript 1.7 被介绍并计划在 ECMAScript 7, array comprehensions 被规范化并提供一个有用的快捷方式,用来实现如何在另一个数组的基础上构造一个新的数组。推导式可以经常被用在那些需要调用 map()filter()函数的地方,或作为一种结合这两种方式。

+ +

下面的推导式创建一个数字数组并且创建一个新的数组,数组的每个元素都是原来数值的两倍(译者注:这种形式类似于Python的列表推导式)。

+ +
var numbers = [1, 2, 3, 4];
+var doubled = [for (i of numbers) i * 2];
+console.log(doubled); // logs 2,4,6,8
+
+ +

这跟下面的map()方法的操作是等价的。

+ +
var doubled = numbers.map(function(i){return i * 2;});
+
+ +

推导式也可以用来筛选满足条件表达式的元素. 下面的推导式用来筛选是2的倍数的元素:

+ +
var numbers = [1, 2, 3, 21, 22, 30];
+var evens = [i for (i of numbers) if (i % 2 === 0)];
+console.log(evens); // logs 2,22,30
+
+ +

filter() 也可以达到相同的目的:

+ +
var evens = numbers.filter(function(i){return i % 2 === 0;});
+
+ +

map() 和filter() 类型的操作可以被组合(等效)为单个数组推导式。这里就有一个过滤出偶数,创建一个它的倍数数组的例子:

+ +
var numbers = [1, 2, 3, 21, 22, 30];
+var doubledEvens = [i * 2 for (i of numbers) if (i % 2 === 0)];
+console.log(doubledEvens); // logs 4,44,60
+
+ +

数组推导式隐含了块作用域。新的变量(如例子中的i)类似于是采用 let声明的。这意味着他们不能在推导式以外访问。

+ +

数组推导式的输入不一定必须是数组; 迭代器和生成器 也是可以的。

+ +

甚至字符串也可以用来作为输入; 实现filter或者map行为 (参考上面类似数组行为的对象)如下:

+ +
var str = 'abcdef';
+var consonantsOnlyStr = [c for (c of str) if (!(/[aeiouAEIOU]/).test(c))  ].join(''); // 'bcdf'
+var interpolatedZeros = [c+'0' for (c of str) ].join(''); // 'a0b0c0d0e0f0'
+
+ +

不过,输入形式是不能保存的,所以我们要使用join()回复到一个字符串。

+ +

类型化数组(Typed Arrays )

+ +

JavaScript typed arrays 是类数组对象(array-like object),其提供访问原始二进制数据的机制。 就像你知道的那样, {{jsxref("Array")}} 对象动态增长和收缩,可以有任何JavaScript值。但对于类型化数组,JavaScript引擎执行优化使得这些数组访问速度快速。 随着Web应用程序变得越来越强大,添加音频和视频处理等功能、可以使用 WebSockets 、使用原始数据, 这都需要访问原始的二进制数据,所以专门的优化将有助于JavaScript代码能够快速和容易地操纵原始二进制数据类型的数组。

+ +

缓冲区和视图:类型化的数组结构

+ +

为了实现最大的灵活性和效率,JavaScript类型数组被分解为缓冲(Buffer)和视图(views)。缓冲(由{{jsxref("ArrayBuffer")}} 实现)是代表数据块的对象,它没有格式可言,并没有提供任何机制来访问其内容。为了访问包含在缓冲区中的内存,您需要使用视图。视图提供了一个上下文,即数据类型、起始偏移量和元素数,这些元素将数据转换为实际类型数组。

+ +

Typed arrays in an ArrayBuffer

+ +

ArrayBuffer

+ +

 {{jsxref("ArrayBuffer")}}是一种数据类型,用于表示一个通用的、固定长度的二进制数据缓冲区。你不能直接操纵一个ArrayBuffer中的内容;你需要创建一个数组类型视图或{{jsxref("DataView")}}来代表特定格式的缓冲区,并从而实现读写缓冲区的内容。

+ +

类型数组视图(Typed array views)

+ +

类型数组视图具有自描述性的名字,并且提供数据类型信息,例如Int8, Uint32, Float64等等。如一个特定类型数组视图Uint8ClampedArray. 它意味着数据元素只包含0到255的整数值。它通常用于Canvas数据处理,例如.

+ +

{{page("/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray", "TypedArray_objects")}}

+ +

更多信息参考 JavaScript typed arrays 与参考文档中 {{jsxref("TypedArray")}}对象的不同

+ +

{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Keyed_Collections")}}

diff --git a/files/zh-cn/web/javascript/guide/introduction/index.html b/files/zh-cn/web/javascript/guide/introduction/index.html new file mode 100644 index 0000000000..8a6a283d5c --- /dev/null +++ b/files/zh-cn/web/javascript/guide/introduction/index.html @@ -0,0 +1,147 @@ +--- +title: 介绍 +slug: Web/JavaScript/Guide/Introduction +tags: + - JavaScript + - 指南 +translation_of: Web/JavaScript/Guide/Introduction +--- +
{{jsSidebar("JavaScript 指南")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}
+ +
+

本章节介绍了 JavaScript,并且讨论了它的一些基本概念。

+
+ +

你应该已经掌握哪些知识?

+ +

我们假设你已经掌握了以下基础技能:

+ + + +

去哪里获取有关 JavaScript 的信息?

+ +

MDN 上的 JavaScript 文档包括以下内容:

+ + + +

如果你刚开始学习 JavaScript,请详细阅读 学习区(Learning area)JavaScript 入门 的文章。如果你已经掌握了 JavaScript 基础知识, 你可以通过 JavaScript 参考 来了解更多关于单个(individual)对象和语句的细节。

+ +

什么是 JavaScript?

+ +

JavaScript 是一门跨平台、面向对象的脚本语言,它能使网页可交互(例如拥有复杂的动画,可点击的按钮,通俗的菜单等)。另外还有高级的服务端Javascript版本,例如Node.js,它可以让你在网页上添加更多功能,不仅仅是下载文件(例如在多台电脑之间的协同合作)。在宿主环境(例如 web 浏览器)中, JavaScript 能够通过其所连接的环境提供的编程接口进行控制。

+ +

JavaScript 内置了一些对象的标准库,比如数组(Array),日期(Date),数学(Math)和一套核心语句,包括运算符、流程控制符以及声明方式等。JavaScript 的核心部分可以通过添加对象来扩展语言以适应不同用途;例如:

+ + + +

这意味着,在浏览器中,JavaScript 可以改变网页(DOM)的外观与样式。同样地,在服务器上,Node.js 中的 JavaScript 可以对浏览器上编写的代码发出的客户端请求做出响应。

+ +

JavaScript 和 Java

+ +

JavaScript 和 Java 有一些共性但是在另一些方面有着根本性区别。JavaScript语言类似 Java 但是并没有 Java 的静态类型和强类型检查特性。JavaScript 遵循了 Java 的表达式语法,命名规范以及基础流程控制,这也是 JavaScript 从 LiveScript 更名的原因。

+ +

与 Java 通过声明的方式构建类的编译时系统不同,JavaScript 采用基于少量的数据类型如数字、布尔、字符串值的运行时系统。JavaScript 拥有基于原型的对象模型提供的动态继承;也就是说,独立对象的继承是可以改变的。 JavaScript 支持匿名函数。 函数也可以作为对象的属性被当做宽松的类型方式执行。

+ +

与 Java 相比,Javascript 是一门形式自由的语言。你不必声明所有的变量,类和方法。你不必关心方法是否是公有、私有或者受保护的,也不需要实现接口。无需显式指定变量、参数、方法返回值的数据类型。

+ +

Java 是基于类的编程语言,设计的初衷就是为了确保快速执行和类型安全。类型安全,举个例子,你不能将一个 Java 整数变量转化为一个对象引用,或者由Java字节码访问专有存储器。Java基于类的模型,意味着程序包含专有的类及其方法。Java的类继承和强类型要求紧耦合的对象层级结构。这些要求使得Java编程比JavaScript要复杂的多。

+ +

相比之下,JavaScript 传承了 HyperTalk 和 dBASE 语句精简、动态类型等精髓,这些脚本语言为更多开发者提供了一种语法简单、内置功能强大以及用最小需求创建对象的编程工具。

+ + + + + + + + + + + + + + + + + + + + + + + +
JavaScript 和 Java 的对比
JavaScriptJava
面向对象。不区分对象类型。通过原型机制继承,任何对象的属性和方法均可以被动态添加。基于类系统。分为类和实例,通过类层级的定义实现继承。不能动态增加对象或类的属性或方法。
变量类型不需要提前声明(动态类型)。变量类型必须提前声明(静态类型)。
不能直接自动写入硬盘。可以直接自动写入硬盘。
+ +

请查看章节 对象模型的详情 来了解更多JavaScript和Java的不同。

+ +

JavaScript 和 ECMAScript 规范

+ +

JavaScript 的标准化组织是 ECMA ——这个欧洲信息与通信系统标准化协会提供基于 Javascript 的标准化方案(ECMA 原先是欧洲计算机制造商协会的首字母缩写)。这种标准化版本的 JavaScript 被称作 ECMAScript,在所有支持该标准的应用中以相同的方式工作。公司可以使用开放标准语言来开发他们自己的 JavaScript 实现版本。ECMAScript 标准在ECMA-262规范中进行文档化。 参照 JavaScript的新特性 以便学习更多关于不同版本的 JavaScript 和 ECMAScript 规范版本。

+ +

ECMA-262 标准也通过了 国际标准化组织(ISO)的 ISO-16262。你可以在这里找到该规范文件。 ECMAScript 规范并没有描述文档对象模型(DOM),该模型由 万维网联盟(W3C) 制定。DOM 定义了HTML文件对象被脚本操作的方法。为了更清楚地了解当使用JavaScript编程时用到的不同技术,请参阅 JavaScript 技术概述

+ +

JavaScript 文献 和 ECMAScript 规范

+ +

ECMAScript规范是实现ECMAScript的一组需求;如果您想在ECMAScript实现或引擎(如Firefox中的SpiderMonkey或Chrome中的V8)中实现符合标准的语言特性,那么它是非常有用的。

+ +

ECMAScript文档不是用来帮助脚本程序员的;使用JavaScript文档获取关于编写脚本的信息。

+ +

ECMAScript规范使用了JavaScript程序员可能不熟悉的术语和语法。尽管ECMAScript中对语言的描述可能有所不同,但语言本身保持不变。JavaScript支持ECMAScript规范中列出的所有功能。

+ +

JavaScript文档描述了适合JavaScript程序员的语言方面。

+ +

JavaScript 入门

+ +

开始使用 JavaScript 很容易,你只需要一个现代 Web 浏览器。这篇教程包含了一些只在最新版本的火狐浏览器上才有的功能,所以建议大家使用最新版本的火狐浏览器。

+ +

火狐内置了两款非常棒的工具用来实验 JavaScript:浏览器控制台和代码草稿纸。

+ +

Web 控制台(Web Console)

+ +

Web 控制台 不仅可以展示当前已加载页面的信息,还包含一个可以在当前页面执行Javascript表达式的 命令行。

+ +

在火狐浏览器菜单栏的 “工具" => "Web开发者" => "Web控制台" 可以打开控制台( 在Windows和Linux上Ctrl+Shift+K ,Mac上Cmd+Option+K) ,它会如期出现在浏览器窗口的底部。如图,最下一行就是可以执行输入的命令行,面板上可以显示执行结果:

+ +

+ +

控制台的工作方式与eval完全相同:返回最后输入的表达式。为了简单起见,可以想象每次输入到控制台的东西实际上都被 console.log 所包围。

+ +
function greetMe(yourName) { alert('Hello ' + yourName); } console.log(eval('3 + 5'));
+ +

代码草稿纸(Scratchpad)

+ +

Web控制台 对于执行单行 JS 命令十分便捷,虽然你也可以执行多行命令,但是在控制台操作并不方便。除此之外,使用控制台你无法保存你的代码片段。因此对于更为复杂的代码片段,Scratchpad(代码草稿纸) 是一个更好的工具。

+ +

从 “Web开发者” 菜单(在火狐浏览器的主菜单下)中选择 “代码草稿纸” 来打开(Shift+F4)。它是一个拥有独立窗口的编辑器,你可以用来编辑和在浏览器中执行 JavaScript。你也可以将代码保存到本地磁盘,或者从本地载入。

+ +

如果你选择显示,草稿纸中的代码会在浏览器中执行,并在内容后面以注释的形式插入返回的结果:

+ +

+ +

Hello world

+ +

学习JavaScript 的第一步,打开浏览器的代码草稿纸尝试编写你的第一个 JavaScript 版本的 “Hello world” 程序。

+ +
function greetMe(user) {
+  alert('Hi ' + user);
+}
+
+greetMe('Alice'); // 'Hi Alice'
+
+ +

在 Scratchpad(代码草稿纸)中选择要执行的代码,然后点击“运行(Ctrl+R)”就可以在浏览器中看到选中代码的执行结果。

+ +

在接下来的章节里,该指南将介绍 JavaScript 的语法以及语言特性,届时你将可以使用它编写更加复杂的程序。

+ +

{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}

diff --git a/files/zh-cn/web/javascript/guide/iterators_and_generators/index.html b/files/zh-cn/web/javascript/guide/iterators_and_generators/index.html new file mode 100644 index 0000000000..07533c60c2 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/iterators_and_generators/index.html @@ -0,0 +1,200 @@ +--- +title: 迭代器和生成器 +slug: Web/JavaScript/Guide/Iterators_and_Generators +tags: + - Generator + - Guide + - Intermediate + - Iterator + - JavaScript + - 中级 + - 生成器 + - 迭代器 +translation_of: Web/JavaScript/Guide/Iterators_and_Generators +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Using_promises", "Web/JavaScript/Guide/Meta_programming")}}
+ +

处理集合中的每个项是很常见的操作。JavaScript 提供了许多迭代集合的方法,从简单的 {{jsxref("Statements/for","for")}} 循环到 {{jsxref("Global_Objects/Array/map","map()")}} 和 {{jsxref("Global_Objects/Array/filter","filter()")}}。迭代器和生成器将迭代的概念直接带入核心语言,并提供了一种机制来自定义 {{jsxref("Statements/for...of","for...of")}} 循环的行为。

+ +

若想了解更多详情,请参考:

+ + + +

迭代器

+ +

在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。 更具体地说,迭代器是通过使用 next() 方法实现 Iterator protocol 的任何一个对象,该方法返回具有两个属性的对象: value,这是序列中的 next 值;和 done ,如果已经迭代到序列中的最后一个值,则它为 true 。如果 value 和 done 一起存在,则它是迭代器的返回值。

+ +

一旦创建,迭代器对象可以通过重复调用next()显式地迭代。 迭代一个迭代器被称为消耗了这个迭代器,因为它通常只能执行一次。 在产生终止值之后,对next()的额外调用应该继续返回{done:true}。
+
+ Javascript中最常见的迭代器是Array迭代器,它只是按顺序返回关联数组中的每个值。 虽然很容易想象所有迭代器都可以表示为数组,但事实并非如此。 数组必须完整分配,但迭代器仅在必要时使用,因此可以表示无限大小的序列,例如0和无穷大之间的整数范围。

+ +


+ 这是一个可以做到这一点的例子。 它允许创建一个简单的范围迭代器,它定义了从开始(包括)到结束(独占)间隔步长的整数序列。 它的最终返回值是它创建的序列的大小,由变量iterationCount跟踪。

+ +
function makeRangeIterator(start = 0, end = Infinity, step = 1) {
+    let nextIndex = start;
+    let iterationCount = 0;
+
+    const rangeIterator = {
+       next: function() {
+           let result;
+           if (nextIndex < end) {
+               result = { value: nextIndex, done: false }
+               nextIndex += step;
+               iterationCount++;
+               return result;
+           }
+           return { value: iterationCount, done: true }
+       }
+    };
+    return rangeIterator;
+}
+ +

使用这个迭代器看起来像这样:

+ +
let it = makeRangeIterator(1, 10, 2);
+
+let result = it.next();
+while (!result.done) {
+ console.log(result.value); // 1 3 5 7 9
+ result = it.next();
+}
+
+console.log("Iterated over sequence of size: ", result.value); // 5
+
+
+ +
+

反射性地知道特定对象是否是迭代器是不可能的。 如果您需要这样做,请使用 Iterables.

+
+ +

生成器函数

+ +

虽然自定义的迭代器是一个有用的工具,但由于需要显式地维护其内部状态,因此需要谨慎地创建。生成器函数提供了一个强大的选择:它允许你定义一个包含自有迭代算法的函数, 同时它可以自动维护自己的状态。 生成器函数使用 {{jsxref("Statements/function*","function*")}}语法编写。 最初调用时,生成器函数不执行任何代码,而是返回一种称为Generator的迭代器。 通过调用生成器的下一个方法消耗值时,Generator函数将执行,直到遇到yield关键字。

+ +

可以根据需要多次调用该函数,并且每次都返回一个新的Generator,但每个Generator只能迭代一次。

+ +

我们现在可以调整上面的例子了。 此代码的行为是相同的,但实现更容易编写和读取。

+ +
function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
+    for (let i = start; i < end; i += step) {
+        yield i;
+    }
+}
+var a = makeRangeIterator(1,10,2)
+a.next() // {value: 1, done: false}
+a.next() // {value: 3, done: false}
+a.next() // {value: 5, done: false}
+a.next() // {value: 7, done: false}
+a.next() // {value: 9, done: false}
+a.next() // {value: undefined, done: true}
+
+ +

可迭代对象

+ +

若一个对象拥有迭代行为,比如在 {{jsxref("Statements/for...of", "for...of")}} 中会循环哪些值,那么那个对象便是一个可迭代对象。一些内置类型,如 {{jsxref("Array")}} 或 {{jsxref("Map")}} 拥有默认的迭代行为,而其他类型(比如{{jsxref("Object")}})则没有。

+ +

为了实现可迭代,一个对象必须实现 @@iterator 方法,这意味着这个对象(或其原型链中的任意一个对象)必须具有一个带 {{jsxref("Symbol.iterator")}} 键(key)的属性。

+ +

可以多次迭代一个迭代器,或者只迭代一次。 程序员应该知道是哪种情况。 只能迭代一次的Iterables(例如Generators)通常从它们的@@iterator方法中返回它本身,其中那些可以多次迭代的方法必须在每次调用@@iterator时返回一个新的迭代器。

+ +

自定义的可迭代对象

+ +

我们可以像这样实现自己的可迭代对象:

+ +
var myIterable = {
+  *[Symbol.iterator]() {
+    yield 1;
+    yield 2;
+    yield 3;
+  }
+}
+
+for (let value of myIterable) {
+    console.log(value);
+}
+// 1
+// 2
+// 3
+
+// 或者
+
+[...myIterable]; // [1, 2, 3]
+
+ +

内置可迭代对象

+ +

{{jsxref("String")}}、{{jsxref("Array")}}、{{jsxref("TypedArray")}}、{{jsxref("Map")}} 和 {{jsxref("Set")}} 都是内置可迭代对象,因为它们的原型对象都拥有一个 {{jsxref("Symbol.iterator")}} 方法。

+ +

用于可迭代对象的语法

+ +

一些语句和表达式专用于可迭代对象,例如 {{jsxref("Statements/for...of","for-of")}} 循环,{{jsxref("Operators/Spread_operator","展开语法")}},{{jsxref("Operators/yield*", "yield*")}} 和 {{jsxref("Operators/Destructuring_assignment", "解构赋值")}}。

+ +
for (let value of ['a', 'b', 'c']) {
+    console.log(value);
+}
+// "a"
+// "b"
+// "c"
+
+[...'abc']; // ["a", "b", "c"]
+
+function* gen() {
+  yield* ['a', 'b', 'c'];
+}
+
+gen().next(); // { value: "a", done: false }
+
+[a, b, c] = new Set(['a', 'b', 'c']);
+a; // "a"
+
+
+ +

高级生成器

+ +

生成器会按需计算它们的产生值,这使得它们能够有效的表示一个计算成本很高的序列,甚至是如上所示的一个无限序列。

+ +

The {{jsxref("Global_Objects/Generator/next","next()")}} 方法也接受一个参数用于修改生成器内部状态。传递给 next() 的参数值会被yield接收。要注意的是,传给第一个 next() 的值会被忽略。

+ +

下面的是斐波那契数列生成器,它使用了 next(x) 来重新启动序列:

+ +
function* fibonacci() {
+  var fn1 = 0;
+  var fn2 = 1;
+  while (true) {
+    var current = fn1;
+    fn1 = fn2;
+    fn2 = current + fn1;
+    var reset = yield current;
+    if (reset) {
+        fn1 = 0;
+        fn2 = 1;
+    }
+  }
+}
+
+var sequence = fibonacci();
+console.log(sequence.next().value);     // 0
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 2
+console.log(sequence.next().value);     // 3
+console.log(sequence.next().value);     // 5
+console.log(sequence.next().value);     // 8
+console.log(sequence.next(true).value); // 0
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 2
+ +

你可以通过调用其 {{jsxref("Global_Objects/Generator/throw","throw()")}} 方法强制生成器抛出异常,并传递应该抛出的异常值。这个异常将从当前挂起的生成器的上下文中抛出,就好像当前挂起的 yield 是一个 throw value 语句。

+ +

如果在抛出的异常处理期间没有遇到 yield,则异常将通过调用 throw() 向上传播,对 next() 的后续调用将导致 done 属性为 true

+ +

生成器具有 {{jsxref("Global_Objects/Generator/return","return(value)")}} 方法,返回给定的值并完成生成器本身。

+ +

{{PreviousNext("Web/JavaScript/Guide/Using_promises", "Web/JavaScript/Guide/Meta_programming")}}

diff --git a/files/zh-cn/web/javascript/guide/javascript_overview/index.html b/files/zh-cn/web/javascript/guide/javascript_overview/index.html new file mode 100644 index 0000000000..1828016f32 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/javascript_overview/index.html @@ -0,0 +1,135 @@ +--- +title: JavaScript 概述 +slug: Web/JavaScript/Guide/JavaScript_Overview +tags: + - ECMAScript +translation_of: Web/JavaScript/Guide/Introduction +--- +

本节将介绍并讨论 JavaScript 的基本概念。

+ +

什么是 JavaScript?

+ +

JavaScript 是一种跨平台,面向对象的脚本语言。作为一种小巧且轻量级的语言,JavaScript 无意于独立运行,而是被设计为可以轻易嵌入到其它的产品和应用中,比如 Web 浏览器。在宿主环境中,JavaScript 可以被连接到环境中的对象之上,以提供对其的编程控制。

+ +

核心的 JavaScript 中包含有一组核心的对象,包括 Array,DateMath,以及一组核心的语言要素,包括操作符,控制结构和语句。出于多种目的,可以通过为其增补附加的对象,对核心 JavaScript 加以扩展;例如:

+ + + +

借由 JavaScript 的 LiveConnect 功能,您可以让 Java 和 JavaScript 间实现通讯。从 JavaScript 中,您可以创建 Java 对象并访问它们的公共方法和域。从 Java 中,也可以访问 JavaScript 的对象,属性和方法。

+ +

Netscape 发明了 JavaScript 并将 JavaScript 首先用于 Netscape 浏览器中。

+ +

JavaScript 和 Java

+ +

JavaScript 和 Java 虽然在某些方面相似,但在另外一些方面确有着本质的不同。JavaScript 语言类似于 Java 语言,但是没有 Java 的类型静态化和强类型检查。JavaScript 大部分的表达式语法,命名规范以及基本的控制流构成都和 Java 相同。正是由于这个原因,JavaScript 才从 LiveScript 改名得来。

+ +

不同于 Java 的通过声明而形成的编译时的类系统,JavaScript 支持基于少量数据类型的运行时系统,这些数据类型用以表示数值、布尔值和字符串。JavaScript 使用基于原型的对象模型,而不是更常见的基于类的对象模型。基于原型的对象模型提供了动态的继承能力,实际上,究竟什么得到继承,对于每个对象都可能不同。JavaScript 还支持无需任何特殊的声明要求的函数。函数可以作为对象的属性,当成松散类型方法(loosely typed method)来执行。

+ +

相比 Java 而言,JavaScript 是一种格式相当自由的语言。无需声明所有的变量,类和方法。无需关心方法是公共的,私有的或者是保护的,也无需实现接口。变量,参数,以及返回值都无需显式的类型声明。

+ +

Java 是基于类的编程语言,目标在于快速的执行和类型安全。这里的类型安全,可以是比如,你不能将 Java 的整数强制转换为对象引用,或者通过篡改 Java 字节码来达到访问私有内存区域的目的。Java 基于类的模型意味着程序完全由类及其方法构成。这些类的继承以及强类型通常需要紧密耦合的对象层级结构。这些需求使得 Java 编程远比 JavaScript 编程要复杂。

+ +

相比之下,JavaScript 的设计理念源于一系列更小巧的动态类型语言,比如 HyperTalk 和 dBASE。这些脚本语言以其更为简单的语法,更专业化的内建功能,以及最小化的对象创建需求,提供了更为大众化的编程工具。

+ + + + + + + + + + + + + + + + + + + + + + + +
表 1.1 JavaScript 与 Java 的对比
JavaScriptJava
面向对象的。对象的类型间没有区别。继承是基于原型机制实现的,且属性和方法可以动态地添加到任何对象之上。基于类的。对象被划分为类和实例,且所有的继承是通过类的层级结构实现的。类或者实例不能动态地添加属性或方法。
变量的数据类型无需声明(动态化类型)。变量的数据类型必需声明(静态化类型)。
不能自动地写入硬盘不能自动地写入硬盘
+ +

有关 JavaScript 和 Java 之间区别的更多信息,参见 对象模型的细节

+ +

JavaScript 和 ECMAScript 规范

+ +

Netscape 发明了 JavaScript 并将 JavaScript 首先用于 Netscape 浏览器中。不过, Netscape 正在与 Ecma International — 欧洲信息和通讯标准化协会(ECMA 曾是 European Computer Manufacturers Association,既欧洲计算机制造商协会的缩写)一道致力于交付一个基于核心 JavaScript 的,标准化的,国际化的编程语言,既 ECMAScript。ECMAScript 在所有支持该标准的应用程序中具有相同的特性。其它公司可以使用开放的标准语言来开发它们的 JavaScript 实现。ECMAScript 标准在 ECMA-262 规范中加以记述。

+ +

ECMA-262 标准由 ISO(International Organization for Standardization,既国际化标准化组织)批准为 ISO-16262。在 Mozilla 网站上可以找到 PDF 版本的 ECMA-262 (过时的版本)。在 Ecma International 的网站 上也可以找到该规范。ECMAScript 规范没有描述文档对象模型(DOM)。该模型由 World Wide Web Consortium (W3C) 完成标准化。DOM 定义了 HTML 文档对象呈现在脚本中的方式。

+ +

JavaScript 版本和 ECMAScript 版本之间的关系

+ +

Netscape 与 Ecma International 的紧密合作形成了 ECMAScript 规范(ECMA-262)。下面的表格描述了 JavaScript 版本和 ECMAScript 版本之间的关系。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
表 1.2 JavaScript 版本和 ECMAScript 版本
JavaScript 版本与 ECMAScript 版本的关系
JavaScript 1.1ECMA-262,第 1 版 基于 JavaScript 1.1.
JavaScript 1.2ECMA-262 在 JavaScript 1.2 发布时尚未完成。由于以下原因,JavaScript 1.2 并不与 ECMA-262,第 1 版完全兼容: +
    +
  • Netscape 在 JavaScript 1.2 开发了一些新的特性尚未被 ECMA-262 采纳。
  • +
  • ECMA-262 添加了两项新特性:基于 Unicode 的国际化,以及跨平台的一致行为。而 JavaScript 1.2 的某些特性,例如 Date 对象,是依赖于平台的,且具有特定于平台的行为。
  • +
+
JavaScript 1.3JavaScript 1.3 完全兼容于 ECMA-262,第 1 版。
+ JavaScript 1.3 解决了 JavaScript 1.2 与 ECMA-262 之间的不一致性,同时保留了 JavaScript 1.2 中的附加特性,除了  ==!= 被修改以便顺应于 ECMA-262 之外。
JavaScript 1.4JavaScript 1.4 完全兼容于 ECMA-262,第 1 版。
+ ECMAScript 规范的第三版在 JavaScript 1.4 发布时尚未最终完成。
JavaScript 1.5JavaScript 1.5 完全兼容于 ECMA-262,第 3 版。
+ +
注:ECMA-262,第 2 版仅包含对第 1 版规范的细微的编辑性的改动和错误修正。由 Ecma International 的 TC39 工作组发布的最新版本为 ECMAScript 版本 5.1
+ +

JavaScript 参考 中标明了语言中的哪些特性兼容于 ECMAScript。

+ +

JavaScript 将总会包含某些 ECMAScript 规范中所没有的特性;JavaScript 兼容于 ECMAScript,同时提供附加特性。

+ +

JavaScript 文档相较于 ECMAScript 规范

+ +

ECMAScript 规范了实现 ECMAScript 的一组需求;它有助于您确定某项 JavaScript 特性是否也为其它 ECMAScript 的实现所支持。如果您想编写仅仅使用 ECMAScript 所支持的特性的代码,那么您可能需要参考 ECMAScript 规范。

+ +

ECMAScript 文档的目的不在于帮助脚本程序员;关于脚本编写的信息,请参考 JavaScript 文档。

+ +

JavaScript 和 ECMAScript 术语

+ +

ECMAScript 规范使用的术语和语法对于 JavaScript 程序员而言,可能会有点陌生。尽管对语言的描述方式在 ECMAScript 中可能不尽相同,但是语言本身还是相同的。JavaScript 支持 ECMAScript 规范中所勾勒出的全部功能。

+ +

JavaScript 文档描述了语言中适合于 JavaScript 程序员的方面。例如:

+ + + +
{{ PreviousNext("JavaScript/Guide/About", "JavaScript/Guide/Values,_variables,_and_literals") }}
diff --git a/files/zh-cn/web/javascript/guide/keyed_collections/index.html b/files/zh-cn/web/javascript/guide/keyed_collections/index.html new file mode 100644 index 0000000000..0c10c93c2a --- /dev/null +++ b/files/zh-cn/web/javascript/guide/keyed_collections/index.html @@ -0,0 +1,155 @@ +--- +title: 带键的集合 +slug: Web/JavaScript/Guide/Keyed_collections +tags: + - Guide + - JavaScript + - Map + - set + - 集合 +translation_of: Web/JavaScript/Guide/Keyed_collections +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}
+ +

这一章介绍由key值标记的数据容器;Map 和 Set 对象承载的数据元素可以按照插入时的顺序被迭代遍历。

+ +

映射

+ +

Map对象

+ +

ECMAScript 2015 引入了一个新的数据结构来将一个值映射到另一个值。一个{{jsxref("Map")}}对象就是一个简单的键值对映射集合,可以按照数据插入时的顺序遍历所有的元素。

+ +

下面的代码演示了使用Map进行的一些基本操作。请参考{{jsxref("Map")}}以获取更多的样例和完整的 API。你可以使用{{jsxref("Statements/for...of","for...of")}}循环来得到所有的[key, value]

+ +
var sayings = new Map();
+sayings.set('dog', 'woof');
+sayings.set('cat', 'meow');
+sayings.set('elephant', 'toot');
+sayings.size; // 3
+sayings.get('fox'); // undefined
+sayings.has('bird'); // false
+sayings.delete('dog');
+sayings.has('dog'); // false
+
+for (var [key, value] of sayings) {
+  console.log(key + ' goes ' + value);
+}
+// "cat goes meow"
+// "elephant goes toot"
+
+sayings.clear();
+sayings.size; // 0
+ +

ObjectMap的比较

+ +

一般地,{{jsxref("Object", "objects", "", 1)}}会被用于将字符串类型映射到数值。Object允许设置键值对、根据键获取值、删除键、检测某个键是否存在。而Map具有更多的优势。

+ + + +

这三条提示可以帮你决定用Map还是Object

+ + + +

WeakMap对象

+ +

{{jsxref("WeakMap")}}对象也是键值对的集合。它的键必须是对象类型,值可以是任意类型。它的键被弱保持,也就是说,当其键所指对象没有其他地方引用的时候,它会被GC回收掉。WeakMap提供的接口与Map相同。

+ +

Map对象不同的是,WeakMap的键是不可枚举的。不提供列出其键的方法。列表是否存在取决于垃圾回收器的状态,是不可预知的。

+ +

可以在"Why WeakMap?"{{jsxref("WeakMap")}}查看更多信息和示例。

+ +

WeakMap对象的一个用例是存储一个对象的私有数据或隐藏实施细节。Nick Fitzgerald 的博文"Hiding Implementation Details with ECMAScript 6 WeakMaps"提供了一个例子。对象内部的私有数据和方法被存储在WeakMap类型的privates变量中。所有暴露出的原型和情况都是公开的,而其他内容都是外界不可访问的,因为模块并未导出privates对象。

+ +
const privates = new WeakMap();
+
+function Public() {
+  const me = {
+    // Private data goes here
+  };
+  privates.set(this, me);
+}
+
+Public.prototype.method = function () {
+  const me = privates.get(this);
+  // Do stuff with private data in `me`...
+};
+
+module.exports = Public;
+
+ +

集合

+ +

Set对象

+ +

{{jsxref("Set")}}对象是一组值的集合,这些值是不重复的,可以按照添加顺序来遍历。

+ +

这里演示了Set的基本操作,更多示例和完整API可以参考{{jsxref("Set")}}。

+ +
var mySet = new Set();
+mySet.add(1);
+mySet.add("some text");
+mySet.add("foo");
+
+mySet.has(1); // true
+mySet.delete("foo");
+mySet.size; // 2
+
+for (let item of mySet) console.log(item);
+// 1
+// "some text"
+
+ +

数组和集合的转换

+ +

可以使用{{jsxref("Array.from")}}或展开操作符来完成集合到数组的转换。同样,Set的构造器接受数组作为参数,可以完成从ArraySet的转换。需要重申的是,Set对象中的值不重复,所以数组转换为集合时,所有重复值将会被删除。

+ +
Array.from(mySet);
+[...mySet2];
+
+mySet2 = new Set([1,2,3,4]);
+
+ +

ArraySet的对比

+ +

一般情况下,在JavaScript中使用数组来存储一组元素,而新的集合对象有这些优势:

+ + + +

WeakSet对象

+ +

{{jsxref("WeakSet")}}对象是一组对象的集合。WeakSet中的对象不重复且不可枚举

+ +

与{{jsxref("Set")}}对象的主要区别有:

+ + + +

WeakSet的用例很有限,比如使用DOM元素作为键来追踪它们而不必担心内存泄漏。

+ +

Map的键和Set的值的等值判断

+ +

Map的键和Set的值的等值判断都基于same-value-zero algorithm

+ + + +

{{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}

diff --git a/files/zh-cn/web/javascript/guide/loops_and_iteration/index.html b/files/zh-cn/web/javascript/guide/loops_and_iteration/index.html new file mode 100644 index 0000000000..9c82f49588 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/loops_and_iteration/index.html @@ -0,0 +1,409 @@ +--- +title: 循环与迭代 +slug: Web/JavaScript/Guide/Loops_and_iteration +tags: + - JavaScript + - 循环 + - 指南 + - 语法 +translation_of: Web/JavaScript/Guide/Loops_and_iteration +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}
+ +

循环提供了一种快速和简单的方式去做一些重复的事。JavaScript入门的这个章节会介绍在JavaScript中存在哪些不同的迭代语句。

+ +

你可以把循环想成一种计算机化的游戏,告诉某人在一个方向上走X步,然后在另一个方向上走Y步;例如,“向东走5步”可以用一个循环来这样表达:

+ +
var step;
+for (step = 0; step < 5; step++) {
+  // Runs 5 times, with values of step 0 through 4.
+  console.log('Walking east one step');
+}
+
+ +

循环有很多种类,但本质上它们都做的是同一件事:它们把一个动作重复了很多次(实际上重复的次数有可能为 0)。各种循环机制提供了不同的方法去确定循环的开始和结束。不同情况下,某一种类型循环会比其它的循环用起来更简单。

+ +

JavaScript中提供了这些循环语句:

+ + + +

for 语句

+ +

一个 {{jsxref("statements/for","for")}} 循环会一直重复执行,直到指定的循环条件为 false。 JavaScript 的 for 循环,和 Java、C 的 for 循环,是很相似的。一个 for 语句是这个样子的:

+ +
for ([initialExpression]; [condition]; [incrementExpression])
+  statement
+
+ +

当一个 for 循环执行的时候,会发生以下过程:

+ +
    +
  1. 如果有初始化表达式 initialExpression,它将被执行。这个表达式通常会初始化一个或多个循环计数器,但语法上是允许一个任意复杂度的表达式的。这个表达式也可以声明变量。
  2. +
  3. 计算 condition 表达式的值。如果 condition 的值是 true,循环中的语句会被执行。如果 condition 的值是 false,for 循环终止。如果 condition 表达式整个都被省略掉了,condition的值会被认为是true。
  4. +
  5. 循环中的 statement 被执行。如果需要执行多条语句,可以使用块({ ... })来包裹这些语句。
  6. +
  7. 如果有更新表达式 incrementExpression,执行更新表达式。
  8. +
  9. 回到步骤 2。
  10. +
+ +

例子

+ +

下面的函数包含一个含有 for 循环去计算一个滑动列表中被选中项目的个数(一个 {{HTMLElement("select")}} 元素允许选择多项)。for 循环声明了变量i并将它的初始值设为 0。它检查 i 是否比 <select> 元素中的选项数量少,执行了随后的 if 语句,然后在每次完成循环后,i 的值增加 1。

+ +
<form name="selectForm">
+  <p>
+    <label for="musicTypes">Choose some music types, then click the button below:</label>
+    <select id="musicTypes" name="musicTypes" multiple="multiple">
+      <option selected="selected">R&B</option>
+      <option>爵士</option>
+      <option>布鲁斯</option>
+      <option>新纪元</option>
+      <option>古典</option>
+      <option>歌剧</option>
+    </select>
+  </p>
+  <p><input id="btn" type="button" value="选择了多少个选项?" /></p>
+</form>
+
+<script>
+function howMany(selectObject) {
+  var numberSelected = 0;
+  for (var i = 0; i < selectObject.options.length; i++) {
+    if (selectObject.options[i].selected) {
+      numberSelected++;
+    }
+  }
+  return numberSelected;
+}
+
+var btn = document.getElementById("btn");
+btn.addEventListener("click", function(){
+  alert('选择选项的数量是: ' + howMany(document.selectForm.musicTypes))
+});
+</script>
+
+
+ +

do...while 语句

+ +

{{jsxref("statements/do...while", "do...while")}} 语句一直重复直到指定的条件求值得到假值(false)。 一个 do...while 语句看起来像这样:

+ +
do
+  statement
+while (condition);
+
+ +

statement 在检查条件之前会执行一次。要执行多条语句(语句块),要使用块语句({ ... })包括起来。 如果 condition 为真(true),statement 将再次执行。 在每个执行的结尾会进行条件的检查。当 condition 为假(false),执行会停止并且把控制权交回给 do...while 后面的语句。

+ +

例子

+ +

在下面的例子中, 这个 do 循环将至少重复一次,并且一直重复直到 i 不再小于 5。

+ +
var i = 0;
+do {
+  i += 1;
+  console.log(i);
+} while (i < 5);
+ +

while 语句

+ +

一个 {{jsxref("statements/while","while")}} 语句只要指定的条件求值为真(true)就会一直执行它的语句块。一个 while 语句看起来像这样:

+ +
while (condition)
+  statement
+
+ +

如果这个条件变为假,循环里的 statement 将会停止执行并把控制权交回给 while 语句后面的代码。

+ +

条件检测会在每次 statement 执行之前发生。如果条件返回为真, statement 会被执行并紧接着再次测试条件。如果条件返回为假,执行将停止并把控制权交回给 while 后面的语句。

+ +

要执行多条语句(语句块),要使用语句块 ({ ... }) 包括起来。

+ +

例子 1

+ +

只要 n 小于 3,下面的 while 循环就会一直执行:

+ +
var n = 0;
+var x = 0;
+while (n < 3) {
+  n++;
+  x += n;
+}
+
+ +

在每次循环里, n 会增加 1,并被加到 x 上。所以, x 和 n 的变化是:

+ + + +

在三次完成后, 条件 n < 3 的结果不再为真,所以循环终止了。

+ +

例子 2

+ +

避免无穷循环(无限循环)。保证循环的条件结果最终会变成假;否则,循环永远不会停止。因为条件永远不会变成假值,下面这个 while 循环将会永远执行:

+ +
while (true) {
+  console.log("Hello, world");
+}
+ +

label 语句

+ +

一个 {{jsxref("statements/label","label")}} 提供了一个让你在程序中其他位置引用它的标识符。例如,你可以用 label 标识一个循环, 然后使用 break 或者 continue 来指出程序是否该停止循环还是继续循环。

+ +

label 语句的语法看起来像这样:

+ +
label :
+   statement
+
+ +

label 的值可以是任何的非保留字的 JavaScript 标识符, statement 可以是任意你想要标识的语句(块)。

+ +

例子

+ +

在这个例子里,标记 markLoop 标识了一个 while 循环。

+ +
markLoop:
+while (theMark == true) {
+   doSomething();
+}
+ +

举一个比较典型的例子,看完后即明白 Label 的应用:

+ +

未添加 Label:

+ +
var num = 0;
+for (var i = 0 ; i < 10 ; i++) {   // i 循环
+  for (var j = 0 ; j < 10 ; j++) { // j 循环
+    if( i == 5 && j == 5 ) {
+       break; // i = 5,j = 5 时,会跳出 j 循环
+    } // 但 i 循环会继续执行,等于跳出之后又继续执行更多次 j 循环
+  num++;
+  }
+}
+
+alert(num); // 输出 95
+ +

添加 Label 后:

+ +
var num = 0;
+outPoint:
+for (var i = 0 ; i < 10 ; i++){
+  for (var j = 0 ; j < 10 ; j++){
+    if( i == 5 && j == 5 ){
+      break outPoint; // 在 i = 5,j = 5 时,跳出所有循环,
+                      // 返回到整个 outPoint 下方,继续执行
+    }
+    num++;
+  }
+}
+
+alert(num); // 输出 55
+ +

使用 continue 语句,则可达到与未添加 label 相同的效果,但在这种有多层循环的情况下,循环的跳出进入流程更为明晰一些:

+ +
var num = 0;
+outPoint:
+for(var i = 0; i < 10; i++) {
+  for(var j = 0; j < 10; j++) {
+    if(i == 5 && j == 5) {
+      continue outPoint;
+    }
+    num++;
+  }
+}
+alert(num);  // 95
+ +

从alert(num)的值可以看出,continue outPoint; 语句的作用是跳出当前循环,并跳转到outPoint(标签)下的 for 循环继续执行。

+ +

break 语句

+ +

使用 {{jsxref("statements/break","break")}} 语句来终止循环,switch, 或者是链接到 label 语句。

+ + + +

break 语句的语法看起来像这样:

+ +
break [label];
+ +

在语法中,被 [] 包裹的内容是可省略的,也就是 label 可以省略。若省略,则终止当前所在的循环或 switch;若不省略,则终止指定的 label 语句。

+ +

例子 1

+ +

下面的例子循环数组里的元素,直到找到一个等于 theValue 的值:

+ +
for (i = 0; i < a.length; i++) {
+  if (a[i] == theValue) {
+    break;
+  }
+}
+ +

例子 2: 终止一个 label

+ +
var x = 0;
+var z = 0
+labelCancelLoops: while (true) {
+  console.log("外部循环: " + x);
+  x += 1;
+  z = 1;
+  while (true) {
+    console.log("内部循环: " + z);
+    z += 1;
+    if (z === 10 && x === 10) {
+      break labelCancelLoops;
+    } else if (z === 10) {
+      break;
+    }
+  }
+}
+
+ +

continue 语句

+ +

{{jsxref("statements/continue","continue")}} 语句可以用来继续执行(跳过代码块的剩余部分并进入下一循环)一个 whiledo-whilefor,或者 label 语句。

+ + + +

continue 语句的语法看起来像这样:

+ +
continue [label];
+
+ +

例子 1

+ +

The following example shows a while loop with a continue statement that executes when the value of i is three. Thus, n takes on the values one, three, seven, and twelve.

+ +
var i = 0;
+var n = 0;
+while (i < 5) {
+  i++;
+  if (i == 3) {
+    continue;
+  }
+  n += i;
+  console.log(n);
+}
+//1,3,7,12
+
+ +
var i = 0;
+var n = 0;
+while (i < 5) {
+  i++;
+  if (i == 3) {
+     // continue;
+  }
+  n += i;
+  console.log(n);
+}
+// 1,3,6,10,15
+ +

例子 2

+ +

一个被标签为 checkiandj 的语句包含了一个标签为 checkj 的语句。

+ +

如果遇到 continue 语句,程序会结束当前 chechj 的迭代并开始下一轮的迭代。

+ +

每次遇到 continue 语句时,checkj 语句会一直重复执行,直到 checkj 语句的条件为 false

+ +

当返回 false 后,将会执行 checkiandj 的剩余语句,checkiandj 会一直执行,直到 checkiandj 的条件为 false

+ +

checkiandj 的返回值为 false 时,将会执行 checkiandj 的下面的语句。

+ +

如果 continue 有一个标记 checkiandj, 程序将会从 checkiandj 语句块的顶部继续执行。

+ +
var i = 0;
+var j = 10;
+checkiandj:
+  while (i < 4) {
+    console.log(i);
+    i += 1;
+    checkj:
+      while (j > 4) {
+        console.log(j);
+        j -= 1;
+        if ((j % 2) == 0) {
+          continue checkj;
+        }
+        console.log(j + ' 是奇数。');
+      }
+      console.log('i = ' + i);
+      console.log('j = ' + j);
+  }
+ +

for...in 语句

+ +

{{jsxref("statements/for...in","for...in")}} 语句循环一个指定的变量来循环一个对象所有可枚举的属性。JavaScript 会为每一个不同的属性执行指定的语句。

+ +
for (variable in object) {
+  statements
+}
+
+ +

例子

+ +

下面的函数通过它的参数得到一个对象和这个对象的名字。然后循环这个对象的所有属性并且返回一个列出属性名和该属性值的字符串。

+ +
function dump_props(obj, obj_name) {
+  var result = "";
+  for (var i in obj) {
+    result += obj_name + "." + i + " = " + obj[i] + "<br>";
+  }
+  result += "<hr>";
+  return result;
+}
+
+ +

对于一个拥有 makemodel 属性的 car 对象来说,执行结果 result 是:

+ +
car.make = Ford
+car.model = Mustang
+
+ +

数组

+ +

虽然使用 for...in 来迭代数组 {{jsxref("Array")}} 元素听起来很诱人,但是它返回的东西除了数字索引外,还有可能是你自定义的属性名字。因此还是用带有数字索引的传统的 {{jsxref("statements/for","for")}} 循环来迭代一个数组比较好,因为,如果你想改变数组对象,比如添加属性或者方法,for...in 语句迭代的是自定义的属性,而不是数组的元素。(译者注:下面的 for...of 语句,和 forEach(),也是理想的选择。)

+ +

for...of 语句

+ +

{{jsxref("statements/for...of","for...of")}} 语句在可迭代对象(包括{{jsxref("Array")}}、{{jsxref("Map")}}、{{jsxref("Set")}}、{{jsxref("functions/arguments","arguments")}} 等等)上创建了一个循环,对值的每一个独特属性调用一次迭代。

+ +
for (variable of object) {
+  statement
+}
+
+ +

下面的这个例子展示了 for...of 和 {{jsxref("statements/for...in","for...in")}} 两种循环语句之间的区别。 for...in 循环遍历的结果是数组元素的下标,而 for...of 遍历的结果是元素的值:

+ +
let arr = [3, 5, 7];
+arr.foo = "hello";
+
+for (let i in arr) {
+   console.log(i); // 输出 "0", "1", "2", "foo"
+}
+
+for (let i of arr) {
+   console.log(i); // 输出 "3", "5", "7"
+}
+
+// 注意 for...of 的输出没有出现 "hello"
+// 译者:官方文档不知为何在此使用三个空格来缩进…
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}

diff --git a/files/zh-cn/web/javascript/guide/meta_programming/index.html b/files/zh-cn/web/javascript/guide/meta_programming/index.html new file mode 100644 index 0000000000..723165c93f --- /dev/null +++ b/files/zh-cn/web/javascript/guide/meta_programming/index.html @@ -0,0 +1,264 @@ +--- +title: 元编程 +slug: Web/JavaScript/Guide/Meta_programming +tags: + - Guide + - JavaScript + - Proxy + - Reflect +translation_of: Web/JavaScript/Guide/Meta_programming +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Iterators_and_Generators", "Web/JavaScript/Guide/Modules")}}
+ +

从ECMAScript 2015 开始,JavaScript 获得了 {{jsxref("Proxy")}} 和 {{jsxref("Reflect")}} 对象的支持,允许你拦截并定义基本语言操作的自定义行为(例如,属性查找,赋值,枚举,函数调用等)。借助这两个对象,你可以在 JavaScript 元级别进行编程。

+ +

代理

+ +

在 ECMAScript 6 中引入的 {{jsxref("Proxy")}} 对象可以拦截某些操作并实现自定义行为。例如获取一个对象上的属性:

+ +
let handler = {
+  get: function(target, name){
+    return name in target ? target[name] : 42;
+}};
+
+let p = new Proxy({}, handler);
+p.a = 1;
+
+console.log(p.a, p.b); // 1, 42
+
+ +

Proxy 对象定义了一个目标(这里是一个空对象)和一个实现了 get 陷阱的 handler 对象。这里,代理的对象在获取未定义的属性时不会返回 undefined,而是返回 42。

+ +

更多例子参见 {{jsxref("Proxy")}} 页面 。

+ +

术语

+ +

在讨论代理的功能时会用到以下术语。

+ +
+
{{jsxref("Global_Objects/Proxy/handler","handler")}}
+
包含陷阱的占位符对象。
+
traps
+
提供属性访问的方法。这类似于操作系统中陷阱的概念。
+
target
+
代理虚拟化的对象。它通常用作代理的存储后端。根据目标验证关于对象不可扩展性或不可配置属性的不变量(保持不变的语义)。
+
invariants
+
实现自定义操作时保持不变的语义称为不变量。如果你违反处理程序的不变量,则会抛出一个 {{jsxref("TypeError")}}。
+
+ +

句柄和陷阱

+ +

以下表格中总结了 Proxy 对象可用的陷阱。详细的解释和例子请看参考页

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Handler / trapInterceptionsInvariants
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}{{jsxref("Object.getPrototypeOf()")}}
+ {{jsxref("Reflect.getPrototypeOf()")}}
+ {{jsxref("Object/proto", "__proto__")}}
+ {{jsxref("Object.prototype.isPrototypeOf()")}}
+ {{jsxref("Operators/instanceof", "instanceof")}}
+
    +
  • getPrototypeOf方法一定返回一个对象或null.
  • +
  • 如果 target 不可扩展,Object.getPrototypeOf(proxy) 必须返回和 Object.getPrototypeOf(target)一样的值。
  • +
+
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}{{jsxref("Object.setPrototypeOf()")}}
+ {{jsxref("Reflect.setPrototypeOf()")}}
如果 target 不可扩展,prototype 参数必须与Object.getPrototypeOf(target)的值相同。
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}{{jsxref("Object.isExtensible()")}}
+ {{jsxref("Reflect.isExtensible()")}}
Object.isExtensible(proxy) 必须返回和Object.isExtensible(target)一样的值。
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}{{jsxref("Object.preventExtensions()")}}
+ {{jsxref("Reflect.preventExtensions()")}}
 如果Object.isExtensible(proxy) 值为 false,Object.preventExtensions(proxy) 只返回true。
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}{{jsxref("Object.getOwnPropertyDescriptor()")}}
+ {{jsxref("Reflect.getOwnPropertyDescriptor()")}}
+
    +
  • getOwnPropertyDescripton 只能返回对象或者undefined.
  • +
  • A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
  • +
  • A property cannot be reported as non-existent, if it exists as an own property of the target object and the target object is not extensible.
  • +
  • A property cannot be reported as existent, if it does not exists as an own property of the target object and the target object is not extensible.
  • +
  • A property cannot be reported as non-configurable, if it does not exists as an own property of the target object or if it exists as a configurable own property of the target object.
  • +
  • The result of Object.getOwnPropertyDescriptor(target) can be applied to the target object using Object.defineProperty and will not throw an exception.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}{{jsxref("Object.defineProperty()")}}
+ {{jsxref("Reflect.defineProperty()")}}
+
    +
  • A property cannot be added, if the target object is not extensible.
  • +
  • A property cannot be added as or modified to be non-configurable, if it does not exists as a non-configurable own property of the target object.
  • +
  • A property may not be non-configurable, if a corresponding configurable property of the target object exists.
  • +
  • If a property has a corresponding target object property then Object.defineProperty(target, prop, descriptor) will not throw an exception.
  • +
  • In strict mode, a false return value from the defineProperty handler will throw a {{jsxref("TypeError")}} exception.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}Property query: foo in proxy
+ Inherited property query: foo in Object.create(proxy)
+ {{jsxref("Reflect.has()")}}
+
    +
  • A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
  • +
  • A property cannot be reported as non-existent, if it exists as an own property of the target object and the target object is not extensible.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}Property access: proxy[foo]and proxy.bar
+ Inherited property access: Object.create(proxy)[foo]
+ {{jsxref("Reflect.get()")}}
+
    +
  • The value reported for a property must be the same as the value of the corresponding target object property if the target object property is a non-writable, non-configurable data property.
  • +
  • The value reported for a property must be undefined if the corresponding target object property is non-configurable accessor property that has undefined as its [[Get]] attribute.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}Property assignment: proxy[foo] = bar and proxy.foo = bar
+ Inherited property assignment: Object.create(proxy)[foo] = bar
+ {{jsxref("Reflect.set()")}}
+
    +
  • Cannot change the value of a property to be different from the value of the corresponding target object property if the corresponding target object property is a non-writable, non-configurable data property.
  • +
  • Cannot set the value of a property if the corresponding target object property is a non-configurable accessor property that has undefined as its [[Set]] attribute.
  • +
  • In strict mode, a false return value from the set handler will throw a {{jsxref("TypeError")}} exception.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}Property deletion: delete proxy[foo] and delete proxy.foo
+ {{jsxref("Reflect.deleteProperty()")}}
A property cannot be deleted, if it exists as a non-configurable own property of the target object.
{{jsxref("Global_Objects/Proxy/handler/enumerate", "handler.enumerate()")}}Property enumeration / for...in: for (var name in proxy) {...}
+ {{jsxref("Reflect.enumerate()")}}
The enumerate method must return an object.
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}{{jsxref("Object.getOwnPropertyNames()")}}
+ {{jsxref("Object.getOwnPropertySymbols()")}}
+ {{jsxref("Object.keys()")}}
+ {{jsxref("Reflect.ownKeys()")}}
+
    +
  • The result of ownKeys is a List.
  • +
  • The Type of each result List element is either {{jsxref("String")}} or {{jsxref("Symbol")}}.
  • +
  • The result List must contain the keys of all non-configurable own properties of the target object.
  • +
  • If the target object is not extensible, then the result List must contain all the keys of the own properties of the target object and no other values.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}proxy(..args)
+ {{jsxref("Function.prototype.apply()")}} and {{jsxref("Function.prototype.call()")}}
+ {{jsxref("Reflect.apply()")}}
There are no invariants for the handler.apply method.
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}new proxy(...args)
+ {{jsxref("Reflect.construct()")}}
结果一定是一个Object
+ +

撤销 Proxy

+ +

{{jsxref("Proxy.revocable()")}} 方法被用来创建可撤销的 Proxy 对象。这意味着 proxy 可以通过 revoke 函数来撤销,并且关闭代理。此后,代理上的任意的操作都会导致{{jsxref("TypeError")}}。

+ +
var revocable = Proxy.revocable({}, {
+  get: function(target, name) {
+    return "[[" + name + "]]";
+  }
+});
+var proxy = revocable.proxy;
+console.log(proxy.foo); // "[[foo]]"
+
+revocable.revoke();
+
+console.log(proxy.foo); // TypeError is thrown
+proxy.foo = 1           // TypeError again
+delete proxy.foo;       // still TypeError
+typeof proxy            // "object", typeof doesn't trigger any trap
+ +

反射

+ +

{{jsxref("Reflect")}} 是一个内置对象,它提供了可拦截 JavaScript 操作的方法。该方法和{{jsxref("Global_Objects/Proxy/handler","代理句柄")}}类似,但 Reflect 方法并不是一个函数对象。

+ +

Reflect 有助于将默认操作从处理程序转发到目标。

+ +

以 {{jsxref("Reflect.has()")}} 为例,你可以将 in 运算符作为函数:

+ +
Reflect.has(Object, "assign"); // true
+
+ +

更好的 apply 函数

+ +

在 ES5 中,我们通常使用 {{jsxref("Function.prototype.apply()")}} 方法调用一个具有给定 this 值和 arguments 数组(或类数组对象)的函数。

+ +
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
+ +

使用 {{jsxref("Reflect.apply")}},这变得不那么冗长和容易理解:

+ +
Reflect.apply(Math.floor, undefined, [1.75]);
+// 1;
+
+Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
+// "hello"
+
+Reflect.apply(RegExp.prototype.exec, /ab/, ['confabulation']).index;
+// 4
+
+Reflect.apply(''.charAt, 'ponies', [3]);
+// "i"
+ +

检查属性定义是否成功

+ +

使用 {{jsxref("Object.defineProperty")}},如果成功返回一个对象,否则抛出一个 {{jsxref("TypeError")}},你将使用 {{jsxref("Statements/try...catch","try...catch")}} 块来捕获定义属性时发生的任何错误。因为 {{jsxref("Reflect.defineProperty")}} 返回一个布尔值表示的成功状态,你可以在这里使用 {{jsxref("Statements/if...else","if...else")}} 块:

+ +
if (Reflect.defineProperty(target, property, attributes)) {
+  // success
+} else {
+  // failure
+}
+
+ +

{{Previous("Web/JavaScript/Guide/Iterators_and_Generators")}}

diff --git a/files/zh-cn/web/javascript/guide/modules/index.html b/files/zh-cn/web/javascript/guide/modules/index.html new file mode 100644 index 0000000000..1b0192666f --- /dev/null +++ b/files/zh-cn/web/javascript/guide/modules/index.html @@ -0,0 +1,460 @@ +--- +title: JavaScript modules 模块 +slug: Web/JavaScript/Guide/Modules +tags: + - JavaScript + - 导入 + - 导出 + - 指南 + - 模块 +translation_of: Web/JavaScript/Guide/Modules +--- +
{{jsSidebar("JavaScript Guide")}}{{Previous("Web/JavaScript/Guide/Meta_programming")}}
+ +

这篇指南会给你入门 Javascript 模块的全部信息。

+ +

模块化的背景

+ +

Javascript 程序本来很小——在早期,它们大多被用来执行独立的脚本任务,在你的 web 页面需要的地方提供一定交互,所以一般不需要多大的脚本。过了几年,我们现在有了运行大量 Javascript 脚本的复杂程序,还有一些被用在其他环境(例如 Node.js)。

+ +

因此,近年来,有必要开始考虑提供一种将 JavaScript 程序拆分为可按需导入的单独模块的机制。Node.js 已经提供这个能力很长时间了,还有很多的 Javascript 库和框架 已经开始了模块的使用(例如, CommonJS 和基于 AMD 的其他模块系统 如 RequireJS, 以及最新的 Webpack 和 Babel)。

+ +

好消息是,最新的浏览器开始原生支持模块功能了,这是本文要重点讲述的。这会是一个好事情 — 浏览器能够最优化加载模块,使它比使用库更有效率:使用库通常需要做额外的客户端处理。

+ +

浏览器支持

+ +

使用JavaScript 模块依赖于importexport,浏览器兼容性如下(绿色方框中的数字对应相应平台上支持该功能的发布版本):

+ +

import

+ +

{{Compat("javascript.statements.import")}}

+ +

export

+ +

{{Compat("javascript.statements.export")}}

+ +

介绍一个例子

+ +

为了演示模块的使用,我们创建了一个 simple set of examples ,你可以在Github上找到。这个例子演示了一个简单的模块的集合用来在web页面上创建了一个{{htmlelement("canvas")}} 标签,在canvas上绘制 (并记录有关的信息) 不同形状。

+ +

这的确有点简单,但是保持足够简单能够清晰地演示模块。

+ +
+

Note: 如果你想去下载这个例子在本地运行,你需要通过本地web 服务器去运行。

+
+ +

基本的示例文件的结构

+ +

在我们的第一个例子 (see basic-modules) 文件结构如下:

+ +
index.html
+main.mjs
+modules/
+    canvas.mjs
+    square.mjs
+ +
+

Note: 在这个指南的全部示例项目的文件结构是基本相同的; 需要熟悉上面的内容

+
+ +

modules 目录下的两个模块的描述如下:

+ + + +
+

Note: 在原生JavaScript模块中, 扩展名 .mjs 非常重要,因为使用 MIME-type 为javascript/esm 来导入文件(其他的JavaScript 兼容 MIME-type 像 application/javascript 也可以), 它避免了严格的 MIME 类型检查错误,像 "The server responded with a non-JavaScript MIME type". 除此之外,  .mjs 的扩展名很明了(比如这个就是一个模块,而不是一个传统 JavaScript文件),还能够和其他工具互相适用. 看这个 Google's note for further details.

+
+ +

.mjs 与 .js

+ +

纵观此文,我们使用 .js 扩展名的模块文件,但在其它一些文章中,你可能会看到 .mjs 扩展名的使用。V8推荐了这样的做法,比如有下列理由:

+ + + +

但是我们决定继续使用 .js 扩展名,未来可能会更改。为了使模块可以在浏览器中正常地工作,你需要确保你的服务器能够正常地处理 Content-Type 头,其应该包含 Javascript 的MIME 类型  text/javascript。如果没有这么做,你可能会得到 一个严格 MIME 类型检查错误:“The server responded with a non-JavaScript MIME type (服务器返回了非 JavaScript MIME 类型)”,并且浏览器会拒绝执行相应的 JavaScript 代码。多数服务器可以正确地处理 .js 文件的类型,但是 .mjs 还不行。已经可以正常响应 .mjs 的服务器有 GitHub 页面 和 Node.js 的 http-server

+ +

 如果你已经在使用相应的环境了,那么一切正常。或者如果你还没有,但你知道你在做什么(比如你可以配置服务器以为 .mjs 设置正确的 Content-Type)。但如果你不能控制提供服务,或者用于公开文件发布的服务器,这可能会导致混乱。

+ +

为了学习和保证代码的可移植的目的,我们建议使用 .js

+ +

如果你认为使用 .mjs 仅用于模块带来的清晰性非常重要,但不想引入上面描述的相应问题,你可以仅在开发过程中使用 .mjs,而在构建过程中将其转换为 .js

+ +

另注意:

+ + + +

导出模块的功能

+ +

为了获得模块的功能要做的第一件事是把它们导出来。使用 export 语句来完成。

+ +

最简单的方法是把它(指上面的export语句)放到你想要导出的项前面,比如:

+ +
export const name = 'square';
+
+export function draw(ctx, length, x, y, color) {
+  ctx.fillStyle = color;
+  ctx.fillRect(x, y, length, length);
+
+  return {
+    length: length,
+    x: x,
+    y: y,
+    color: color
+  };
+}
+ +

你能够导出函数,varletconst, 和等会会看到的类。export要放在最外层;比如你不能够在函数内使用export

+ +

一个更方便的方法导出所有你想要导出的模块的方法是在模块文件的末尾使用一个export 语句, 语句是用花括号括起来的用逗号分割的列表。比如:

+ +
export { name, draw, reportArea, reportPerimeter };
+ +

导入功能到你的脚本

+ +

你想在模块外面使用一些功能,那你就需要导入他们才能使用。最简单的就像下面这样的:

+ +
import { name, draw, reportArea, reportPerimeter } from '/js-examples/modules/basic-modules/modules/square.mjs';
+ +

使用 import 语句,然后你被花括号包围的用逗号分隔的你想导入的功能列表,然后是关键字from,然后是模块文件的路径。模块文件的路径是相对于站点根目录的相对路径,对于我们的basic-modules 应该是 /js-examples/modules/basic-modules

+ +

当然,我们写的路径有一点不同---我们使用点语法意味 “当前路径”,跟随着包含我们想要找的文件的路径。这比每次都要写下整个相对路径要好得多,因为它更短,使得URL 可移植 ---如果在站点层中你把它移动到不同的路径下面仍然能够工作。(修订版 1889482)

+ +

那么看看例子吧:

+ +
/js/examples/modules/basic-modules/modules/square.mjs
+ +

变成了

+ +
./modules/square.mjs
+ +

你可以在main.mjs中看到这些。

+ +
+

Note:在一些模块系统中你可以忽略文件扩展名(比如'/model/squre' .这在原生JavaScript 模块系统中不工作。此外,记住你需要包含最前面的正斜杠。   (修订版 1889482)

+
+ +

因为你导入了这些功能到你的脚本文件,你可以像定义在相同的文件中的一样去使用它。下面展示的是在 main.mjs 中的import 语句下面的内容。

+ +
let myCanvas = create('myCanvas', document.body, 480, 320);
+let reportList = createReportList(myCanvas.id);
+
+let square1 = draw(myCanvas.ctx, 50, 50, 100, 'blue');
+reportArea(square1.length, reportList);
+reportPerimeter(square1.length, reportList);
+
+ +

应用模块到你的HTML

+ +

现在我们只需要将main.mjs模块应用到我们的HTML页面。 这与我们将常规脚本应用于页面的方式非常相似,但有一些显着的差异。

+ +

首先,你需要把 type="module" 放到 {{htmlelement("script")}} 标签中, 来声明这个脚本是一个模块:

+ +
<script type="module" src="main.mjs"></script>
+ +

你导入模块功能的脚本基本是作为顶级模块。 如果省略它,Firefox就会给出错误“SyntaxError: import declarations may only appear at top level of a module。

+ +

你只能在模块内部使用 importexport 语句 ;不是普通脚本文件。

+ +
+

Note: 您还可以将模块导入内部脚本,只要包含 type="module",例如 <script type="module"> //include script here </script>.

+
+ +

其他模块与标准脚本的不同

+ + + +

默认导出 versus 命名导出

+ +

到目前为止我们导出的功能都是由named exports 组成— 每个项目(无论是函数,常量等)在导出时都由其名称引用,并且该名称也用于在导入时引用它。

+ +

还有一种导出类型叫做 default export —这样可以很容易地使模块提供默认功能,并且还可以帮助JavaScript模块与现有的CommonJS和AMD模块系统进行互操作(正如ES6 In Depth: Modules by Jason Orendorff的模块中所解释的那样;搜索“默认导出”“)。

+ +

看个例子来解释它如何工作。在我们的基本模块square.mjs中,您可以找到一个名为randomSquare()的函数,它创建一个具有随机颜色,大小和位置的正方形。我们想作为默认导出,所以在文件的底部我们这样写 :

+ +
export default randomSquare;
+ +

注意,不要大括号。

+ +

我们可以把 export default 放到函数前面,定义它为一个匿名函数,像这样:

+ +
export default function(ctx) {
+  ...
+}
+ +

在我们的main.mjs 文件中,我们使用以下行导入默认函数:

+ +
import randomSquare from './modules/square.mjs';
+ +

同样,没有大括号,因为每个模块只允许有一个默认导出, 我们知道 randomSquare 就是需要的那个。上面的那一行相当于下面的缩写:

+ +
import {default as randomSquare} from './modules/square.mjs';
+ +
+

Note: 重命名导出项的as语法在下面的{{anch("Renaming imports and exports")}}部分中进行了说明。

+
+ +

避免命名冲突

+ +

到目前为止,我们的canvas 图形绘制模块看起来工作的很好。但是如果我们添加一个绘制其他形状的比如圆形或者矩形的模块会发生什么?这些形状可能会有相关的函数比如 draw()reportArea(),等等;如果我们用相同的名字导入不同的函数到顶级模块文件中,我们会收到冲突和错误。

+ +

幸运的是,有很多方法来避免。我们将会在下一个节看到。

+ +

重命名导出与导入

+ +

在你的 import 和 export 语句的大括号中,可以使用 as 关键字跟一个新的名字,来改变你在顶级模块中将要使用的功能的标识名字。因此,例如,以下两者都会做同样的工作,尽管方式略有不同:

+ +
// inside module.mjs
+export {
+  function1 as newFunctionName,
+  function2 as anotherNewFunctionName
+};
+
+// inside main.mjs
+import { newFunctionName, anotherNewFunctionName } from '/modules/module.mjs';
+ +
// inside module.mjs
+export { function1, function2 };
+
+// inside main.mjs
+import { function1 as newFunctionName,
+         function2 as anotherNewFunctionName } from '/modules/module.mjs';
+ +

让我们看一个真实的例子。在我们的重命名目录中,您将看到与上一个示例中相同的模块系统,除了我们添加了circle.mjstriangle.mjs模块以绘制和报告圆和三角形。

+ +

在每个模块中,我们都有export 相同名称的功能,因此每个模块底部都有相同的导出语句:

+ +
export { name, draw, reportArea, reportPerimeter };
+ +

将它们导入main.mjs时,如果我们尝试使用

+ +
import { name, draw, reportArea, reportPerimeter } from './modules/square.mjs';
+import { name, draw, reportArea, reportPerimeter } from './modules/circle.mjs';
+import { name, draw, reportArea, reportPerimeter } from './modules/triangle.mjs';
+ +

浏览器会抛出一个错误,例如“SyntaxError: redeclaration of import name”(Firefox)。

+ +

相反,我们需要重命名导入,使它们是唯一的:

+ +
import { name as squareName,
+         draw as drawSquare,
+         reportArea as reportSquareArea,
+         reportPerimeter as reportSquarePerimeter } from './modules/square.mjs';
+
+import { name as circleName,
+         draw as drawCircle,
+         reportArea as reportCircleArea,
+         reportPerimeter as reportCirclePerimeter } from './modules/circle.mjs';
+
+import { name as triangleName,
+        draw as drawTriangle,
+        reportArea as reportTriangleArea,
+        reportPerimeter as reportTrianglePerimeter } from './modules/triangle.mjs';
+ +

请注意,您可以在模块文件中解决问题,例如

+ +
// in square.mjs
+export { name as squareName,
+         draw as drawSquare,
+         reportArea as reportSquareArea,
+         reportPerimeter as reportSquarePerimeter };
+ +
// in main.mjs
+import { squareName, drawSquare, reportSquareArea, reportSquarePerimeter } from '/js-examples/modules/renaming/modules/square.mjs';
+ +

它也会起作用。 你使用什么样的风格取决于你,但是单独保留模块代码并在导入中进行更改可能更有意义。 当您从没有任何控制权的第三方模块导入时,这尤其有意义。

+ +

创建模块对象

+ +

上面的方法工作的挺好,但是有一点点混乱、亢长。一个更好的解决方是,导入每一个模块功能到一个模块功能对象上。可以使用以下语法形式:

+ +
import * as Module from '/modules/module.mjs';
+ +

这将获取module.mjs中所有可用的导出,并使它们可以作为对象模块的成员使用,从而有效地为其提供自己的命名空间。 例如:

+ +
Module.function1()
+Module.function2()
+etc.
+ +

再次,让我们看一个真实的例子。如果您转到我们的module-objects目录,您将再次看到相同的示例,但利用上述的新语法进行重写。在模块中,导出都是以下简单形式:

+ +
export { name, draw, reportArea, reportPerimeter };
+ +

另一方面,导入看起来像这样:

+ +
import * as Canvas from './modules/canvas.mjs';
+
+import * as Square from '/./modules/square.mjs';
+import * as Circle from './modules/circle.mjs';
+import * as Triangle from './modules/triangle.mjs';
+ +

在每种情况下,您现在可以访问指定对象名称下面的模块导入

+ +
let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, 'blue');
+Square.reportArea(square1.length, reportList);
+Square.reportPerimeter(square1.length, reportList);
+ +

因此,您现在可以像以前一样编写代码(只要您在需要时包含对象名称),并且导入更加整洁。

+ +

模块与类(class)

+ +

正如我们之前提到的那样,您还可以导出和导入类; 这是避免代码冲突的另一种选择,如果您已经以面向对象的方式编写了模块代码,那么它尤其有用。

+ +

您可以在我们的classes 目录中看到使用ES类重写的形状绘制模块的示例。 例如,square.mjs 文件现在包含单个类中的所有功能:

+ +
class Square {
+  constructor(ctx, listId, length, x, y, color) {
+    ...
+  }
+
+  draw() {
+    ...
+  }
+
+  ...
+}
+ +

然后我们导出:

+ +
export { Square };
+ +

main.mjs中,我们像这样导入它:

+ +
import { Square } from './modules/square.mjs';
+ +

然后使用该类绘制我们的方块:

+ +
let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue');
+square1.draw();
+square1.reportArea();
+square1.reportPerimeter();
+ +

合并模块

+ +

有时你会想要将模块聚合在一起。 您可能有多个级别的依赖项,您希望简化事物,将多个子模块组合到一个父模块中。 这可以使用父模块中以下表单的导出语法:

+ +
export * from 'x.mjs'
+export { name } from 'x.mjs'
+ +
+

Note: 这实际上是导入后跟导出的简写,即“我导入模块x.mjs,然后重新导出部分或全部导出”。

+
+ +

有关示例,请参阅我们的module-aggregation。 在这个例子中(基于我们之前的类示例),我们有一个名为shapes.mjs的额外模块,它将circle.mjssquare.mjsriangle.mjs中的所有功能聚合在一起。 我们还将子模块移动到名为shapes的modules目录中的子目录中。 所以模块结构现在是这样的:

+ +
modules/
+  canvas.mjs
+  shapes.mjs
+  shapes/
+    circle.mjs
+    square.mjs
+    triangle.mjs
+ +

在每个子模块中,输出具有相同的形式,例如,

+ +
export { Square };
+ +

接下来是聚合部分。 在shapes.mjs里面,我们包括以下几行:

+ +
export { Square } from '/js-examples/modules/module-aggregation/modules/shapes/square.mjs';
+export { Triangle } from '/js-examples/modules/module-aggregation/modules/shapes/triangle.mjs';
+export { Circle } from '/js-examples/modules/module-aggregation/modules/shapes/circle.mjs';
+ +

它们从各个子模块中获取导出,并有效地从shapes.mjs模块中获取它们。

+ +
+

Note: 即使shapes.mjs文件位于modules目录中,我们仍然需要相对于模块根目录编写这些URL,因此需要/modules/。 这是使用JavaScript模块时混淆的常见原因。

+
+ +
+

Note: shapes.mjs中引用的导出基本上通过文件重定向,并且实际上并不存在,因此您将无法在同一文件中编写任何有用的相关代码。

+
+ +

所以现在在main.mjs 文件中,我们可以通过替换来访问所有三个模块类

+ +
import { Square } from './modules/square.mjs';
+import { Circle } from './modules/circle.mjs';
+import { Triangle } from './modules/triangle.mjs';
+ +

使用以下单行:

+ +
import { Square, Circle, Triangle } from './modules/shapes.mjs';
+ +

动态加载模块

+ +

浏览器中可用的JavaScript模块功能的最新部分是动态模块加载。 这允许您仅在需要时动态加载模块,而不必预先加载所有模块。 这有一些明显的性能优势; 让我们继续阅读,看看它是如何工作的。

+ +

这个新功能允许您将import()作为函数调用,将其作为参数传递给模块的路径。 它返回一个 promise,它用一个模块对象来实现(参见{{anch("Creating a module object")}}),让你可以访问该对象的导出,例如

+ +
import('/modules/myModule.mjs')
+  .then((module) => {
+    // Do something with the module.
+  });
+ +

我们来看一个例子。 在dynamic-module-imports 目录中,我们有另一个基于类示例的示例。 但是这次我们在示例加载时没有在画布上绘制任何东西。 相反,我们包括三个按钮 - “圆形”,“方形”和“三角形” - 按下时,动态加载所需的模块,然后使用它来绘制相关的形状。

+ +

在这个例子中,我们只对index.htmlmain.mjs文件进行了更改 - 模块导出保持与以前相同。

+ +

main.mjs中,我们使用document.querySelector()调用获取了对每个按钮的引用,例如:

+ +
let squareBtn = document.querySelector('.square');
+ +

然后,我们为每个按钮附加一个事件监听器,以便在按下时,相关模块被动态加载并用于绘制形状:

+ +
squareBtn.addEventListener('click', () => {
+  import('/js-examples/modules/dynamic-module-imports/modules/square.mjs').then((Module) => {
+    let square1 = new Module.Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue');
+    square1.draw();
+    square1.reportArea();
+    square1.reportPerimeter();
+  })
+});
+ +

请注意,由于promise履行会返回一个模块对象,因此该类成为对象的子特征,因此我们现在需要使用 Module访问构造函数。 在它之前,例如 Module.Square( ... )

+ +

故障排除

+ +

如果为了你的模块有问题,这里有一些提示有可能帮助到你。如果你发现更多的内容欢迎添加进来!

+ + + +

参见

+ + + +

{{Previous("Web/JavaScript/Guide/Meta_programming")}}

diff --git a/files/zh-cn/web/javascript/guide/numbers_and_dates/index.html b/files/zh-cn/web/javascript/guide/numbers_and_dates/index.html new file mode 100644 index 0000000000..392c659766 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/numbers_and_dates/index.html @@ -0,0 +1,407 @@ +--- +title: 数字和日期 +slug: Web/JavaScript/Guide/Numbers_and_dates +tags: + - JavaScript + - 指南 +translation_of: Web/JavaScript/Guide/Numbers_and_dates +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}
+ +
本章节介绍了在JavaScript中使用数字和日期来处理和执行计算的概念,对象和函数。
+ +

本章节介绍如何掌握Javascript里的数字和日期类型

+ +

数字

+ +

在 JavaScript 里面,数字均为双精度浮点类型(double-precision 64-bit binary format IEEE 754),即一个介于±2−1023和±2+1024之间的数字,或约为±10−308到±10+308,数字精度为53位。整数数值仅在±(253 - 1)的范围内可以表示准确。

+ +

除了能够表示浮点数,数字类型也还能表示三种符号值: +{{jsxref("Infinity")}}(正无穷)、-{{jsxref("Infinity")}}(负无穷)和 {{jsxref("NaN")}} (not-a-number,非数字)。

+ +

JavaScript最近添加了 {{jsxref("BigInt")}} 的支持,能够用于表示极大的数字。使用 BigInt 的时候有一些注意事项,例如,你不能让 BigInt 和 {{jsxref("Number")}} 直接进行运算,你也不能用 {{jsxref("Math")}} 对象去操作 BigInt 数字。

+ +

请参见Javascript指南中的 JavaScript 数据类型和数据结构 ,了解其他更多的基本类型。

+ +

您可以使用四种数字进制:十进制,二进制,八进制和十六进制。

+ +

十进制数字(Decimal numbers)

+ +
1234567890
+42
+// 以零开头的数字的注意事项:
+0888 // 888 将被当做十进制处理
+0777 // 在非严格格式下会被当做八进制处理 (用十进制表示就是511)
+
+ +

请注意,十进制可以以0开头,后面接其他十进制数字,但是假如下一个接的十进制数字小于8,那么该数字将会被当做八进制处理。

+ +

二进制数字(Binary numbers)

+ +

二进制数字语法是以零为开头,后面接一个小写或大写的拉丁文字母B(0b或者是0B)。 假如0b后面的数字不是0或者1,那么就会提示这样的语法错误( SyntaxError): "Missing binary digits after 0b(0b之后缺失二有效的二进制数据)"。

+ +
var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
+var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
+var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607
+ +

八进制数字(Octal numbers)

+ +

八进制数字语法是以0为开头的。假如0后面的数字不在0到7的范围内,该数字将会被转换成十进制数字。

+ +
var n = 0755; // 493
+var m = 0644; // 420
+
+ +

在ECMAScript 5 严格模式下禁止使用八进制语法。八进制语法并不是ECMAScript 5规范的一部分,但是通过在八进制数字添加一个前缀0就可以被所有的浏览器支持:0644 === 420 而且 "\045" === "%"。在ECMAScript 6中使用八进制数字是需要给一个数字添加前缀"0o"。

+ +
var a = 0o10; // ES6 :八进制
+ +

十六进制(Hexadecimal numbers)

+ +

十六进制数字语法是以零为开头,后面接一个小写或大写的拉丁文字母X(0x或者是0X)。假如0x后面的数字超出规定范围(0123456789ABCDEF),那么就会提示这样的语法错误(SyntaxError):"Identifier starts immediately after numeric literal".

+ +
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
+0x123456789ABCDEF   // 81985529216486900
+0XA                 // 10
+
+ +

指数形式(Exponentiation)

+ +
1E3   // 1000
+2e6   // 2000000
+0.1e2 // 10
+
+ +

数字对象

+ +

内置的{{jsxref("Number")}}对象有一些有关数字的常量属性,如最大值、不是一个数字和无穷大的。你不能改变这些属性,但可以按下边的方式使用它们:

+ +
var biggestNum = Number.MAX_VALUE;
+var smallestNum = Number.MIN_VALUE;
+var infiniteNum = Number.POSITIVE_INFINITY;
+var negInfiniteNum = Number.NEGATIVE_INFINITY;
+var notANum = Number.NaN;
+
+ +

你永远只用从Number对象引用上边显示的属性,而不是你自己创建的Number对象的属性。

+ +

下面的表格汇总了数字对象的属性:

+ +

数字的属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性描述
{{jsxref("Number.MAX_VALUE")}}可表示的最大值
{{jsxref("Number.MIN_VALUE")}}可表示的最小值
{{jsxref("Number.NaN")}}特指”非数字“
{{jsxref("Number.NEGATIVE_INFINITY")}}特指“负无穷”;在溢出时返回
{{jsxref("Number.POSITIVE_INFINITY")}}特指“正无穷”;在溢出时返回
{{jsxref("Number.EPSILON")}} +

表示1和比最接近1且大于1的最小{{jsxref("Number")}}之间的差别

+
{{jsxref("Number.MIN_SAFE_INTEGER")}}JavaScript最小安全整数.
{{jsxref("Number.MAX_SAFE_INTEGER")}}JavaScript最大安全整数.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
数字的方法
方法描述
{{jsxref("Number.parseFloat()")}}把字符串参数解析成浮点数,
+ 和全局方法 {{jsxref("parseFloat", "parseFloat()")}} 作用一致.
{{jsxref("Number.parseInt()")}} +

把字符串解析成特定基数对应的整型数字,和全局方法 {{jsxref("parseInt", "parseInt()")}} 作用一致.

+
{{jsxref("Number.isFinite()")}}判断传递的值是否为有限数字。
{{jsxref("Number.isInteger()")}}判断传递的值是否为整数。
{{jsxref("Number.isNaN()")}}判断传递的值是否为 {{jsxref("Global_Objects/NaN", "NaN")}}. More robust version of the original global {{jsxref("Global_Objects/isNaN", "isNaN()")}}.
{{jsxref("Number.isSafeInteger()")}}判断传递的值是否为安全整数。
+ +

数字的类型提供了不同格式的方法以从数字对象中检索信息。以下表格总结了 数字类型原型上的方法。

+ + + + + + + + + + + + + + + + + + + + + + + +
数字类型原型上的一些方法
方法描述
{{jsxref("Number.toExponential", "toExponential()")}}返回一个数字的指数形式的字符串,形如:1.23e+2
{{jsxref("Number.toFixed", "toFixed()")}} +

返回指定小数位数的表示形式,

+ +

var a=123,b=a.toFixed(2)//b="123.00"

+
{{jsxref("Number.toPrecision", "toPrecision()")}} +

返回一个指定精度的数字。如下例子中,a=123中,3会由于精度限制消失

+ +

var a=123,b=a.toPrecision(2)//b="1.2e+2"

+
+ +

数学对象(Math)

+ +

对于内置的{{jsxref("Math")}}数学常项和函数也有一些属性和方法。 比方说, Math对象的 PI 属性会有属性值 pi (3.141...),你可以像这样调用它:

+ +
Math.PI // π
+
+ +

同理,标准数学函数也是Math的方法。 这些包括三角函数​​,对数,指数,和其他函数。比方说你想使用三角函数 sin, 你可以这么写:

+ +
Math.sin(1.56)
+
+ +

需要注意的是Math的所有三角函数参数都是弧度制。

+ +

下面的表格总结了 Math 对象的方法。

+ +

Math的方法

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
方法描述
{{jsxref("Math.abs", "abs()")}}绝对值
{{jsxref("Math.sin", "sin()")}}, {{jsxref("Math.cos", "cos()")}}, {{jsxref("Math.tan", "tan()")}}标准三角函数;参数为弧度
{{jsxref("Math.asin", "asin()")}}, {{jsxref("Math.acos", "acos()")}}, {{jsxref("Math.atan", "atan()")}}, {{jsxref("Math.atan2", "atan2()")}}反三角函数; 返回值为弧度
{{jsxref("Math.sinh", "sinh()")}}, {{jsxref("Math.cosh", "cosh()")}}, {{jsxref("Math.tanh", "tanh()")}}双曲三角函数; 返回值为弧度.
{{jsxref("Math.asinh", "asinh()")}}, {{jsxref("Math.acosh", "acosh()")}}, {{jsxref("Math.atanh", "atanh()")}}反双曲三角函数;返回值为弧度.
+

{{jsxref("Math.pow", "pow()")}}, {{jsxref("Math.exp", "exp()")}}, {{jsxref("Math.expm1", "expm1()")}}, {{jsxref("Math.log10", "log10()")}}, {{jsxref("Math.log1p", "log1p()")}}, {{jsxref("Math.log2", "log2()")}}

+
指数与对数函数
{{jsxref("Math.floor", "floor()")}}, {{jsxref("Math.ceil", "ceil()")}}返回最大/最小整数小于/大于或等于参数
{{jsxref("Math.min", "min()")}}, {{jsxref("Math.max", "max()")}} +

返回一个以逗号间隔的数字参数列表中的较小或较大值(分别地)

+
{{jsxref("Math.random", "random()")}}返回0和1之间的随机数。
{{jsxref("Math.round", "round()")}}, {{jsxref("Math.fround", "fround()")}}, {{jsxref("Math.trunc", "trunc()")}},四舍五入和截断函数
{{jsxref("Math.sqrt", "sqrt()")}}, {{jsxref("Math.cbrt", "cbrt()")}}, {{jsxref("Math.hypot", "hypot()")}} +

平方根,立方根,平方参数的和的平方根 

+ +

两个参数平方和的平方根

+
{{jsxref("Math.sign", "sign()")}}数字的符号, 说明数字是否为正、负、零。
{{jsxref("Math.clz32", "clz32()")}},
+ {{jsxref("Math.imul", "imul()")}}
+

在32位2进制表示中,开头的0的数量.

+ +

返回传入的两个参数相乘结果的类C的32位表现形式

+
+ +

和其他对象不同,你不能够创建一个自己的Math对象。你只能使用内置的Math对象。

+ +

日期对象

+ +

JavaScript没有日期数据类型。但是你可以在你的程序里使用 {{jsxref("Date")}} 对象和其方法来处理日期和时间。Date对象有大量的设置、获取和操作日期的方法。 它并不含有任何属性。

+ +

JavaScript 处理日期数据类似于Java。这两种语言有许多一样的处理日期的方法,也都是以1970年1月1日00:00:00以来的毫秒数来储存数据类型的。

+ +

Date 对象的范围是相对距离 UTC 1970年1月1日 的前后 100,000,000 天。

+ +

创建一个日期对象:

+ +
var dateObjectName = new Date([parameters]);
+
+ +

这里的 dateObjectName 对象是所创建的Date对象的一个名字,它可以成为一个新的对象或者已存在的其他对象的一个属性。

+ +

不使用 new 关键字来调用Date对象将返回当前时间和日期的字符串

+ +

前边的语法中的参数(parameters)可以是一下任何一种:

+ + + +

Date对象的方法

+ +

处理日期时间的Date对象方法可分为以下几类:

+ + + +

通过“get”和“set”方法,你可以分别设置和获取秒,分,时,日,星期,月份,年。这里有个getDay方法可以返回星期,但是没有相应的setDay方法用来设置星期,因为星期是自动设置的。这些方法用整数来代表以下这些值:

+ + + +

例如, 假设你定义了如下日期:

+ +
var Xmas95 = new Date("December 25, 1995");
+
+ +

Then Xmas95.getMonth() 返回 11, and Xmas95.getFullYear() 返回 1995.

+ +

getTime 和 setTime 方法对于比较日期是非常有用的。getTime方法返回从1970年1月1日00:00:00的毫秒数。

+ +

例如,以下代码展示了今年剩下的天数:

+ +
var today = new Date();
+var endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // 设置日和月,注意,月份是0-11
+endYear.setFullYear(today.getFullYear()); // 把年设置为今年
+var msPerDay = 24 * 60 * 60 * 1000; // 每天的毫秒数
+var daysLeft = (endYear.getTime() - today.getTime()) / msPerDay;
+var daysLeft = Math.round(daysLeft); //返回今年剩下的天数
+
+ +

这个例子中,创建了一个包含今天的日期的Date对象,并命名为today,然后创建了一个名为endYearDate对象,并把年份设置为当前年份,接着使用todayendYeargetTime分别获取今天和年底的毫秒数,再根据每一天的毫秒数,计算出了今天到年底的天数,最后四舍五入得到今年剩下的天数。

+ +

parse方法对于从日期字符串赋值给现有的Date对象很有用,例如:以下代码使用parsesetTime分配了一个日期值给IPOdate对象:

+ +
var IPOdate = new Date();
+IPOdate.setTime(Date.parse("Aug 9, 1995"));
+
+ +

例子:

+ +

在下边的例子中,JSClock()函数返回了用数字时钟格式的时间:

+ +
function JSClock() {
+  var time = new Date();
+  var hour = time.getHours();
+  var minute = time.getMinutes();
+  var second = time.getSeconds();
+  var temp = "" + ((hour > 12) ? hour - 12 : hour);
+  if (hour == 0)
+    temp = "12";
+  temp += ((minute < 10) ? ":0" : ":") + minute;
+  temp += ((second < 10) ? ":0" : ":") + second;
+  temp += (hour >= 12) ? " P.M." : " A.M.";
+  return temp;
+}
+
+ +

JSClock函数首先创建了一个叫做time的新的Date对象,因为没有参数,所以time代表了当前日期和时间。然后调用了getHours, getMinutes以及getSeconds方法把当前的时分秒分别赋值给了hourminute,second。

+ +

接下来的4句在time的基础上创建了一个字符串,第一句创建了一个变量temp,并通过一个条件表达式进行了赋值,如果小时大于12,就为 (hour - 12), 其他情况就为 hour, 除非 hour 为 0, 这种情况下,它会变成 12.

+ +

接下来的语句拼接了minute的值到temp后。如果minute小于10,条件表达式就会在minute前边加个0,其他情况下加一个分号。然后按同样的方式在temp后拼接上了秒。

+ +

最后,如果hour是12或者更大,条件表达式会在temp后拼接"P.M.",否则拼接"A.M." 。

+ +

{{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}

diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html new file mode 100644 index 0000000000..a9ef01776b --- /dev/null +++ b/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html @@ -0,0 +1,263 @@ +--- +title: Assertions +slug: Web/JavaScript/Guide/Regular_Expressions/Assertions +tags: + - JavaScript + - 参考 + - 指南 + - 正则 + - 正则表达式 +translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions +--- +

{{jsSidebar("JavaScript Guide")}}

+ +

断言的组成之一是边界。对于文本、词或模式,边界可以用来表明它们的起始或终止部分(如向前断言,向后断言以及条件表达式)。

+ +

{{EmbedInteractiveExample("pages/js/regexp-assertions.html", "taller")}}

+ +

类型

+ +

边界类断言

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
字符含义
^ +

匹配输入的开头。如果多行模式设为 true,^ 在换行符后也能立即匹配,比如 /^A/ 匹配不了 "an A" 里面的 "A",但是可以匹配 "An A" 里面第一个 "A"。

+ +
+

^ 出现在集合或范围开头时的含义与此不同(参见 group)。

+
+
$ +

匹配输入的结束。如果多行模式设为 true,^ 在换行符前也能立即匹配,比如 /t$/ 不能匹配  "eater" 中的 "t",但是可以匹配 "eat" 中的 "t"。

+
\b +

匹配一个单词的边界,这是一个字的字符前后没有另一个字的字符位置, 例如在字母和空格之间。需要注意的是匹配的单词边界不包括在匹配中。换句话说,匹配字边界的长度为零。

+ +

一些例子:

+ +
    +
  • /\bm/  在 "moon" 中匹配到 "m" 
  • +
  • /oo\b/  在 "moon" 中不会匹配到 "oo", 因为 "oo" 后面跟着 "n" 这个单词字符.
  • +
  • /oon\b/ 在 "moon" 中匹配 "oon", 因为 "oon" 是这个字符串的结尾, 因此后面没有单词字符
  • +
  • /\w\b\w/ 将永远不会匹配任何东西,因为一个单词字符后面永远不会有非单词字符和单词字符。
  • +
+ +

匹配退格字符 ([\b]), 查看 字符类 

+
\B +

匹配非单词边界。这是上一个字符和下一个字符属于同一类型的位置:要么两者都必须是单词,要么两者都必须是非单词,例如在两个字母之间或两个空格之间。字符串的开头和结尾被视为非单词。与匹配的词边界相同,匹配的非词边界也不包含在匹配中。例如,/\Bon/ 在 “at noon” 中匹配 “on” ,/ye\B/ 在 "possibly yesterday"中匹配"ye" 。

+
+ +

其他断言 

+ +
+

提示:字符也可用作量词

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
字符含义
+

x(?=y)                

+
+ + + + + + +
向前断言: x 被 y 跟随时匹配 x。例如,对于/Jack(?=Sprat)/,“Jack”在跟有“Sprat”的情况下才会得到匹配./Jack(?=Sprat|Frost)/ “Jack”后跟有“Sprat”或“Frost”的情况下才会得到匹配。不过, 匹配结果不包括“Sprat”或“Frost”。
+
x(?!y) + + + + + + +
向前否定断言: x 没有被 y 紧随时匹配 x。例如,对于/\d+(?!\。)/,数字后没有跟随小数点的情况下才会得到匹配。对于/\d+(?!\.)/.exec(3.141),匹配‘141’而不是‘3’。
+
(?<=y)x + + + + + + +
向后断言: x 跟随 y 的情况下匹配 x。例如,对于/(?<=Jack)Sprat/,“Sprat”紧随“Jack”时才会得到匹配。对于/(?<=Jack|Tom)Sprat,“Sprat”在紧随“Jack”或“Tom”的情况下才会得到匹配。不过,匹配结果中不包括“Jack”或“Tom”。
+
(?<!y)x + + + + + + +
向后否定断言: x 不跟随 y 时匹配 x。例如,对于/(?<!-)\d+/,数字不紧随-符号的情况下才会得到匹配。对于/(?<!-)\d+/.exec(3) ,“3”得到匹配。 而/(?<!-)\d+/.exec(-3)的结果无匹配,这是由于数字之前有-符号。
+
+ +

示例

+ +

一般边界类型概述示例

+ +
// 使用 正则表达式边界修复错误字符串
+buggyMultiline = `tey, ihe light-greon apple
+tangs on ihe greon traa`;
+
+// 1) 使用 ^ 修正字符串开始处和换行后的匹配.
+buggyMultiline = buggyMultiline.replace(/^t/gim,'h');
+console.log(1, buggyMultiline); // 修复 'tey'=>'hey'(字符串开始) , 'tangs'=>'hangs'(换行后)
+
+// 2) 使用 $ 修正字符串结尾处的匹配.
+buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.');
+console.log(2, buggyMultiline); // 修复 'traa' => 'tree'.
+
+// 3) 使用 \b 修正单词和空格边界上的字符.
+buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
+console.log(3, buggyMultiline); // 修复 'ihe' => 'the'  不影响 'light'.
+
+// 4) 使用 \B 匹配实体边界内的字符.
+fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
+console.log(4, fixedMultiline); // 修复  'greon'  不影响'on'.
+ +

使用 ^(控制字符)匹配输入的开头

+ +

使用 ^匹配输入的开头。在这个例子中,我们可以通过 /^A/ 正则表达式得到以A开头的水果。为了选择合适的水果,我们可以使用带有箭头函数的过滤方法.

+ +
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
+// 使用正则 /^A/ 选择以'A'开头的水果.
+// 这里的 '^' 只有一种含义: 匹配输入的开头.
+
+let fruitsStartsWithA = fruits.filter(fruit => /^A/.test(fruit));
+console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]
+ +

在第二个示例中,^用于在输入的开始处匹配,以及在内部使用时用于创建否定或被补充的字符集 组和范围.

+ +
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
+// 使用正则 /^[^A]/ 选择 不是以 ‘A’ 开头的水果
+// 在这个例子中,“^” 控件符号表示两种含义:
+// 1) 匹配输入的开头
+// 2) 一个否定的字符集: [^A] ,意思是匹配不是 ‘A’ 的字符
+
+let fruitsStartsWithNotA = fruits.filter(fruit => /^[^A]/.test(fruit));
+
+console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]
+ +

匹配字边界

+ +
let fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
+
+// 选择包含以 “en” 或 “ed” 结尾的单词的描述:
+let enEdSelection = fruitsWithDescription.filter(descr => /(en|ed)\b/.test(descr));
+
+console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]
+ +

向前断言

+ +
// JS 向前断言 x(?=y) 匹配被 y 跟随的 x
+
+let regex = /First(?= test)/g;
+
+console.log('First test'.match(regex)); // [ 'First' ]
+console.log('test First peach'.match(regex)); // null
+console.log('This is a First test in a year.'.match(regex)); // [ 'First' ]
+console.log('This is a First peach in a month.'.match(regex)); // null
+ +

向前否定断言

+ +

例如, /\d+(?!\.)/ 匹配没有被小数点跟随且至少有一位的数字。 /\d+(?!\.)/.exec('3.141') 匹配 "141" 而不是 "3" 

+ +
console.log(/\d+(?!\.)/g.exec('3.141')); // [ '141', index: 2, input: '3.141' ]
+ +

不同含义的'?!':断言和范围的组合用法

+ +

不同含义的?! 结合使用 断言  /x(?!y)/ 和  范围 [^?!].

+ +
let orangeNotLemon = "Do you want to have an orange? Yes, I do not want to have a lemon!";
+
+let selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi
+console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]
+
+let selectNotOrangeRegex = /[^?!]+have(?! an orange)[^?!]+[?!]/gi
+console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not want to have a lemon!' ]
+ +

向后断言

+ +
let oranges = ['ripe orange A ', 'green orange B', 'ripe orange C',];
+
+let ripe_oranges = oranges.filter( fruit => fruit.match(/(?<=ripe )orange/));
+console.log(ripe_oranges); // [ 'ripe orange A ', 'ripe orange C' ]
+ +

规范

+ + + + + + + + + + +
详述
{{SpecName('ESDraft', '#sec-assertion', 'RegExp: Assertions')}}
+ +

浏览器 兼容性

+ +

有关浏览器兼容性的信息,请查看 main Regular Expressions compatibility table.

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html new file mode 100644 index 0000000000..0c5b2f4eb9 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html @@ -0,0 +1,6 @@ +--- +title: Boundaries +slug: Web/JavaScript/Guide/Regular_Expressions/Boundaries +translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions +--- +

重定向至 断言

diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html new file mode 100644 index 0000000000..26b1f4ee4a --- /dev/null +++ b/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html @@ -0,0 +1,216 @@ +--- +title: 字符类 +slug: Web/JavaScript/Guide/Regular_Expressions/Character_Classes +tags: + - 字符类 +translation_of: Web/JavaScript/Guide/Regular_Expressions/Character_Classes +--- +

{{JSSidebar("JavaScript Guide")}}

+ +

字符类可以区分各种字符,例如区分字母和数字。

+ +
{{EmbedInteractiveExample("pages/js/regexp-character-classes.html")}}
+ +

类型

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CharactersMeaning
. +

有下列含义之一:

+ +
    +
  • 匹配除行终止符之外的任何单个字符: \n, \r, \u2028 or \u2029. 例如, /.y/ 在“yes make my day”中匹配“my”和“ay”,而不是“yes”。
  • +
  • 在字符集内,点失去了它的特殊意义,并与文字点匹配。
  • +
+ +

需要注意的是,m multiline标志不会改变点的行为。因此,要跨多行匹配一个模式,可以使用字符集[^]—它将匹配任何字符,包括新行。

+ +

ES2018 添加了 s "dotAll" 标志,它允许点也匹配行终止符。

+
\d +

匹配任何数字(阿拉伯数字)。 相当于 [0-9]. 例如, /\d/ 或 /[0-9]/ 匹配 “B2is the suite number”中的“2”。

+
\D +

匹配任何非数字(阿拉伯数字)的字符。相当于[^0-9]. 例如, /\D/ or /[^0-9]/ 在 "B2 is the suite number" 中 匹配 "B".

+
\w +

匹配基本拉丁字母中的任何字母数字字符,包括下划线。相当于 [A-Za-z0-9_]. 例如, /\w/ 在 "apple" 匹配 "a" , "5" in "$5.28", "3" in "3D" and "m" in "Émanuel".

+
\W +

匹配任何不是来自基本拉丁字母的单词字符。相当于 [^A-Za-z0-9_]. 例如, /\W/ or /[^A-Za-z0-9_]/ 匹配 "%" 在 "50%" 以及 "É" 在 "Émanuel" 中.

+
\s +

Matches a single white space character, including space, tab, form feed, line feed, and other Unicode spaces. Equivalent to [ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]. For example, /\s\w*/ matches " bar" in "foo bar".

+
\S +

Matches a single character other than white space. Equivalent to [^ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]. For example, /\S\w*/ matches "foo" in "foo bar".

+
\tMatches a horizontal tab.
\rMatches a carriage return.
\nMatches a linefeed.
\vMatches a vertical tab.
\fMatches a form-feed.
[\b]Matches a backspace. If you're looking for the word-boundary character (\b), see Boundaries.
\0Matches a NUL character. Do not follow this with another digit.
\cX +

Matches a control character using caret notation, where "X" is a letter from A–Z (corresponding to codepoints U+0001U+001F). For example, /\cM/ matches "\r" in "\r\n".

+
\xhhMatches the character with the code hh (two hexadecimal digits).
\uhhhhMatches a UTF-16 code-unit with the value hhhh (four hexadecimal digits).
\u{hhhh} or \u{hhhhh}(Only when the u flag is set.) Matches the character with the Unicode value U+hhhh or U+hhhhh (hexadecimal digits).
\ +

Indicates that the following character should be treated specially, or "escaped". It behaves one of two ways.

+ +
    +
  • For characters that are usually treated literally, indicates that the next character is special and not to be interpreted literally. For example, /b/ matches the character "b". By placing a backslash in front of "b", that is by using /\b/, the character becomes special to mean match a word boundary.
  • +
  • For characters that are usually treated specially, indicates that the next character is not special and should be interpreted literally. For example, "*" is a special character that means 0 or more occurrences of the preceding character should be matched; for example, /a*/ means match 0 or more "a"s. To match * literally, precede it with a backslash; for example, /a\*/ matches "a*".
  • +
+ +
+

To match this character literally, escape it with itself. In other words to search for \ use /\\/.

+
+
+ +

Examples

+ +

Looking for a series of digits

+ +
var randomData = "015 354 8787 687351 3512 8735";
+var regexpFourDigits = /\b\d{4}\b/g;
+// \b indicates a boundary (i.e. do not start matching in the middle of a word)
+// \d{4} indicates a digit, four times
+// \b indicates another boundary (i.e. do not end matching in the middle of a word)
+
+
+console.table(randomData.match(regexpFourDigits));
+// ['8787', '3512', '8735']
+
+ +

Looking for a word (from the latin alphabet) starting with A

+ +
var aliceExcerpt = "I’m sure I’m not Ada,’ she said, ‘for her hair goes in such long ringlets, and mine doesn’t go in ringlets at all.";
+var regexpWordStartingWithA = /\b[aA]\w+/g;
+// \b indicates a boundary (i.e. do not start matching in the middle of a word)
+// [aA] indicates the letter a or A
+// \w+ indicates any character *from the latin alphabet*, multiple times
+
+console.table(aliceExcerpt.match(regexpWordStartingWithA));
+// ['Ada', 'and', 'at', 'all']
+
+ +

Looking for a word (from Unicode characters)

+ +

Instead of the Latin alphabet, we can use a range of Unicode characters to identify a word (thus being able to deal with text in other languages like Russian or Arabic). The "Basic Multilingual Plane" of Unicode contains most of the characters used around the world and we can use character classes and ranges to match words written with those characters.

+ +
var nonEnglishText = "Приключения Алисы в Стране чудес";
+var regexpBMPWord = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
+// BMP goes through U+0000 to U+FFFF but space is U+0020
+
+console.table(nonEnglishText.match(regexpBMPWord));
+[ 'Приключения', 'Алисы', 'в', 'Стране', 'чудес' ]
+
+ + + +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-characterclass', 'RegExp: Character classes')}}
+ +

Browser compatibility

+ +

For browser compatibility information, check out the main Regular Expressions compatibility table.

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html new file mode 100644 index 0000000000..9a73c9b8ef --- /dev/null +++ b/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html @@ -0,0 +1,164 @@ +--- +title: Groups and ranges +slug: Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges +translation_of: Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges +--- +

{{jsSidebar("JavaScript Guide")}}

+ +

组和范围表示表达式字符的 组和范围

+ +
{{EmbedInteractiveExample("pages/js/regexp-groups-ranges.html")}}
+ +

类型

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字符集含义
x|y +

匹配 "x" 或 "y" 任意一个字符。例如, /green|red/ 在 "green apple" 里匹配 "green",且在 "red apple" 里匹配 "red" 。

+
[xyz]
+ [a-c]
+

字符集。 匹配任何一个包含的字符。您可以使用连字符来指定字符范围,但如果连字符显示为方括号中的第一个或最后一个字符,则它将被视为作为普通字符包含在字符集中的文字连字符。也可以在字符集中包含字符类。

+ +

例如, [abcd] 是与[a-d].一样的,它们会 在"brisket" 中匹配 "b",在 "chop" 中匹配 "c" .

+ +

例如, [abcd-][-abcd] 将会在 "brisket" 匹配 "b" , 在 "chop" 匹配 "c" , 并且匹配 "non-profit" 中的 "-" (连字符)

+ +

例如, [\w-] 是字符集 \w 和 “-”(连字符)的并集,与这种写法一样: [A-Za-z0-9_-].。他们都会 在 "brisket"中匹配 “b”,  在 "chop"中匹配 “c”, 在 "non-profit" 中匹配 "n"。

+
+

[^xyz]
+ [^a-c]

+
+

一个否定的或被补充的字符集。也就是说,它匹配任何没有包含在括号中的字符。可以通过使用连字符来指定字符范围,但是如果连字符作为方括号中的第一个或最后一个字符出现,那么它将被视为作为普通字符包含在字符集中。例如,[^abc]和[^a-c]一样。它们最初匹配“bacon”中的“o”和“chop”中的“h”。

+ +
+

 ^ 字符也可以表示   输入的起始

+
+
(x) +

捕获组: 匹配x并记住匹配项。例如,/(foo)/匹配并记住“foo bar”中的“foo” 

+ +

正则表达式可以有多个捕获组。结果,匹配通常在数组中捕获的组,该数组的成员与捕获组中左括号的顺序相同。这通常只是捕获组本身的顺序。当捕获组被嵌套时,这一点非常重要。使用结果元素的索引 ([1], ..., [n]) 或从预定义的 RegExp 对象的属性 ($1, ..., $9).

+ +

捕获组会带来性能损失。如果不需要收回匹配的子字符串,请选择非捕获括号(见下面)。

+ +

String.match() 不会返回组,如果设置了 /.../g 标志. 但是,您仍然可以使用 String.matchAll() to get all matches.

+ +

match()不会返回组,如果/…但是,您仍然可以使用String.matchAll()来获取所有匹配项。

+
\n +

其中n是一个正整数。对正则表达式中与n括号匹配的最后一个子字符串的反向引用(计算左括号)。例如,/apple(,)\sorange\1/ 匹配 “apple,orange,cherry,peach” 中的 "apple,orange,", 其中 \1 引用了 之前使用 () 捕获的

+
(?<Name>x) +

具名捕获组: 匹配"x"并将其存储在返回的匹配项的groups属性中,该属性位于<Name>指定的名称下。尖括号(<>) 用于组名。

+ +

例如,使用正则 /-(?<customName>\w)/ 匹配 “web-doc” 中的 “d”

+ +

'web-doc'.match(/-(?<customName>\w)/).groups   //{customName: "d"}    

+
(?:x)非捕获组: 匹配 “x”,但不记得匹配。不能从结果数组的元素中收回匹配的子字符串([1], ..., [n]) or from the predefined RegExp object's properties ($1, ..., $9).
+ +

一些例子

+ +

计算元音数

+ +
var aliceExcerpt = "There was a long silence after this, and Alice could only hear whispers now and then.";
+var regexpVowels = /[aeiouy]/g;
+
+console.log("Number of vowels:", aliceExcerpt.match(regexpVowels).length);
+// Number of vowels: 25
+ +

使用 组

+ +
let personList = `First_Name: John, Last_Name: Doe
+First_Name: Jane, Last_Name: Smith`;
+
+let regexpNames =  /First_Name: (\w+), Last_Name: (\w+)/mg;
+let match = regexpNames.exec(personList);
+do {
+  console.log(`Hello ${match[1]} ${match[2]}`);
+} while((match = regexpNames.exec(personList)) !== null);
+
+ +

使用命名组

+ +
let users= `姓氏: 李, 名字: 雷
+姓氏: 韩, 名字: 梅梅`;
+
+let regexpNames =  /姓氏: (?<first>.+), 名字: (?<last>.+)/mg;
+let match = regexpNames.exec(users);
+
+do {
+  console.log(`Hello ${match.groups.first} ${match.groups.last}`);
+} while((match = regexpNames.exec(users)) !== null);
+
+// Hellow 李 雷
+// Hellow 韩 梅梅
+ +
+

Note: 并不是所有的浏览器都支持这个功能; 参考兼容表: compatibility table.

+
+ +

技术指标

+ + + + + + + + + + +
技术指标
{{SpecName('ESDraft', '#sec-classranges', 'RegExp: Ranges')}}
+ +

浏览器兼容性

+ +

有关浏览器兼容性的信息,请查看 main Regular Expressions compatibility table.

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/index.html new file mode 100644 index 0000000000..4d88167c80 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/regular_expressions/index.html @@ -0,0 +1,745 @@ +--- +title: 正则表达式 +slug: Web/JavaScript/Guide/Regular_Expressions +tags: + - JavaScript + - RegExp + - Regular Expressions + - 中级 + - 参考 + - 指南 + - 正则表达式 +translation_of: Web/JavaScript/Guide/Regular_Expressions +--- +

{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}

+ +

正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。这些模式被用于 {{jsxref("RegExp")}} 的 {{jsxref("RegExp.exec", "exec")}} 和 {{jsxref("RegExp.test", "test")}} 方法, 以及 {{jsxref("String")}} 的 {{jsxref("String.match", "match")}}、{{jsxref("String.matchAll", "matchAll")}}、{{jsxref("String.replace", "replace")}}、{{jsxref("String.search", "search")}} 和 {{jsxref("String.split", "split")}} 方法。本章介绍 JavaScript 正则表达式。

+ +

创建一个正则表达式

+ +

你可以使用以下两种方法构建一个正则表达式:

+ +

使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示:

+ +
var re = /ab+c/;
+
+ +

脚本加载后,正则表达式字面量就会被编译。当正则表达式保持不变时,使用此方法可获得更好的性能。

+ +

或者调用RegExp对象的构造函数,如下所示:

+ +
var re = new RegExp("ab+c");
+
+ +

在脚本运行过程中,用构造函数创建的正则表达式会被编译。如果正则表达式将会改变,或者它将会从用户输入等来源中动态地产生,就需要使用构造函数来创建正则表达式。

+ +

编写一个正则表达式的模式

+ +

一个正则表达式模式是由简单的字符所构成的,比如 /abc/;或者是简单和特殊字符的组合,比如 /ab*c//Chapter (\d+)\.\d*/。最后的例子中用到了括号,它在正则表达式中常用作记忆设备。即这部分所匹配的字符将会被记住以备后续使用,例如使用括号的子字符串匹配

+ +

使用简单模式

+ +

简单模式是由你想直接找到的字符构成。比如,/abc/ 这个模式就能且仅能匹配 "abc" 字符按照顺序同时出现的情况。例如在 "Hi, do you know your abc's?" 和 "The latest airplane designs evolved from slabcraft." 中会匹配成功。在上述两个例子中,匹配的子字符串是 "abc"。但是在 "Grab crab" 中会匹配失败,因为它虽然包含子字符串 "ab c",但并不是准确的 "abc"。

+ +

使用特殊字符

+ +

当你需要匹配一个不确定的字符串时,比如寻找一个或多个 "b",或者寻找空格,可以在模式中使用特殊字符。比如,你可以使用 /ab*c/ 去匹配一个单独的 "a" 后面跟了零个或者多个 "b",同时后面跟着 "c" 的字符串:*的意思是前一项出现零次或者多次。在字符串 "cbbabbbbcdebc" 中,这个模式匹配了子字符串 "abbbbc"。

+ +

下面的页面与表格列出了一个正则表达式中可以利用的特殊字符的完整列表和描述。

+ +
+
断言(Assertions)
+
表示一个匹配在某些条件下发生。断言包含先行断言、后行断言和条件表达式。
+
字符类(Character Classes)
+
区分不同类型的字符,例如区分字母和数字。
+
组和范围(Groups and Ranges)
+
表示表达式字符的分组和范围。
+
量词(Quantifiers)
+
表示匹配的字符或表达式的数量。
+
Unicode 属性转义(Unicode Property Escapes)
+
基于 unicode 字符属性区分字符。例如大写和小写字母、数学符号和标点。
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
正则表达式中的特殊字符
字符含义
\ +

依照下列规则匹配:

+ +

在非特殊字符之前的反斜杠表示下一个字符是特殊字符,不能按照字面理解。例如,前面没有 "\" 的 "b" 通常匹配小写字母 "b",即字符会被作为字面理解,无论它出现在哪里。但如果前面加了 "\",它将不再匹配任何字符,而是表示一个字符边界

+ +

在特殊字符之前的反斜杠表示下一个字符不是特殊字符,应该按照字面理解。详情请参阅下文中的 "转义(Escaping)" 部分。

+ +

如果你想将字符串传递给 RegExp 构造函数,不要忘记在字符串字面量中反斜杠是转义字符。所以为了在模式中添加一个反斜杠,你需要在字符串字面量中转义它。/[a-z]\s/i 和 new RegExp("[a-z]\\s", "i") 创建了相同的正则表达式:一个用于搜索后面紧跟着空白字符(\s 可看后文)并且在 a-z 范围内的任意字符的表达式。为了通过字符串字面量给 RegExp 构造函数创建包含反斜杠的表达式,你需要在字符串级别和正则表达式级别都对它进行转义。例如 /[a-z]:\\/i 和 new RegExp("[a-z]:\\\\","i") 会创建相同的表达式,即匹配类似 "C:\" 字符串。

+
^ +

匹配输入的开始。如果多行标志被设置为 true,那么也匹配换行符后紧跟的位置。

+ +

例如,/^A/ 并不会匹配 "an A" 中的 'A',但是会匹配 "An E" 中的 'A'。

+ +

当 '^' 作为第一个字符出现在一个字符集合模式时,它将会有不同的含义。反向字符集合 一节有详细介绍和示例。

+
$ +

匹配输入的结束。如果多行标志被设置为 true,那么也匹配换行符前的位置。

+ +

例如,/t$/ 并不会匹配 "eater" 中的 't',但是会匹配 "eat" 中的 't'。

+
* +

匹配前一个表达式 0 次或多次。等价于 {0,}

+ +

例如,/bo*/ 会匹配 "A ghost boooooed" 中的 'booooo' 和 "A bird warbled" 中的 'b',但是在 "A goat grunted" 中不会匹配任何内容。

+
+ +

匹配前面一个表达式 1 次或者多次。等价于 {1,}

+ +

例如,/a+/ 会匹配 "candy" 中的 'a' 和 "caaaaaaandy" 中所有的 'a',但是在 "cndy" 中不会匹配任何内容。

+
? +

匹配前面一个表达式 0 次或者 1 次。等价于 {0,1}

+ +

例如,/e?le?/ 匹配 "angel" 中的 'el'、"angle" 中的 'le' 以及 "oslo' 中的 'l'。

+ +

如果紧跟在任何量词 *、 +、? 或 {} 的后面,将会使量词变为非贪婪(匹配尽量少的字符),和缺省使用的贪婪模式(匹配尽可能多的字符)正好相反。例如,对 "123abc" 使用 /\d+/ 将会匹配 "123",而使用 /\d+?/ 则只会匹配到 "1"。

+ +

还用于先行断言中,如本表的 x(?=y)x(?!y) 条目所述。

+
. +

(小数点)默认匹配除换行符之外的任何单个字符。

+ +

例如,/.n/ 将会匹配 "nay, an apple is on the tree" 中的 'an' 和 'on',但是不会匹配 'nay'。

+ +

如果 s ("dotAll") 标志位被设为 true,它也会匹配换行符。

+
(x) +

像下面的例子展示的那样,它会匹配 'x' 并且记住匹配项。其中括号被称为捕获括号

+ +

模式 /(foo) (bar) \1 \2/ 中的 '(foo)' 和 '(bar)' 匹配并记住字符串 "foo bar foo bar" 中前两个单词。模式中的 \1\2 表示第一个和第二个被捕获括号匹配的子字符串,即 foobar,匹配了原字符串中的后两个单词。注意 \1\2、...、\n 是用在正则表达式的匹配环节,详情可以参阅后文的 \n 条目。而在正则表达式的替换环节,则要使用像 $1$2、...、$n 这样的语法,例如,'bar foo'.replace(/(...) (...)/, '$2 $1')$& 表示整个用于匹配的原字符串。

+
(?:x) +

匹配 'x' 但是不记住匹配项。这种括号叫作非捕获括号,使得你能够定义与正则表达式运算符一起使用的子表达式。看看这个例子 /(?:foo){1,2}/。如果表达式是 /foo{1,2}/{1,2} 将只应用于 'foo' 的最后一个字符 'o'。如果使用非捕获括号,则 {1,2} 会应用于整个 'foo' 单词。更多信息,可以参阅下文的 Using parentheses 条目.

+
x(?=y) +

匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言。

+ +

例如,/Jack(?=Sprat)/会匹配到'Jack'仅当它后面跟着'Sprat'。/Jack(?=Sprat|Frost)/匹配‘Jack’仅当它后面跟着'Sprat'或者是‘Frost’。但是‘Sprat’和‘Frost’都不是匹配结果的一部分。

+
(?<=y)x +

匹配'x'仅当'x'前面是'y'.这种叫做后行断言。

+ +

例如,/(?<=Jack)Sprat/会匹配到' Sprat '仅仅当它前面是' Jack '。/(?<=Jack|Tom)Sprat/匹配‘ Sprat ’仅仅当它前面是'Jack'或者是‘Tom’。但是‘Jack’和‘Tom’都不是匹配结果的一部分。

+
x(?!y) +

仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找。

+ +

例如,仅仅当这个数字后面没有跟小数点的时候,/\d+(?!\.)/ 匹配一个数字。正则表达式/\d+(?!\.)/.exec("3.141")匹配‘141’而不是‘3.141’

+
(?<!y)x +

仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找。

+ +

例如, 仅仅当这个数字前面没有负号的时候,/(?<!-)\d+/ 匹配一个数字。
+ /(?<!-)\d+/.exec('3') 匹配到 "3".
+ /(?<!-)\d+/.exec('-3') 因为这个数字前有负号,所以没有匹配到。

+
x|y +

匹配‘x’或者‘y’。

+ +

例如,/green|red/匹配“green apple”中的‘green’和“red apple”中的‘red’

+
{n}n 是一个正整数,匹配了前面一个字符刚好出现了 n 次。
+ 比如, /a{2}/ 不会匹配“candy”中的'a',但是会匹配“caandy”中所有的 a,以及“caaandy”中的前两个'a'。
{n,} +

n是一个正整数,匹配前一个字符至少出现了n次。

+ +

例如, /a{2,}/ 匹配 "aa", "aaaa" 和 "aaaaa" 但是不匹配 "a"。

+
{n,m} +

n 和 m 都是整数。匹配前面的字符至少n次,最多m次。如果 n 或者 m 的值是0, 这个值被忽略。

+ +

例如,/a{1, 3}/ 并不匹配“cndy”中的任意字符,匹配“candy”中的a,匹配“caandy”中的前两个a,也匹配“caaaaaaandy”中的前三个a。注意,当匹配”caaaaaaandy“时,匹配的值是“aaa”,即使原始的字符串中有更多的a。

+
[xyz]一个字符集合。匹配方括号中的任意字符,包括转义序列。你可以使用破折号(-)来指定一个字符范围。对于点(.)和星号(*)这样的特殊符号在一个字符集中没有特殊的意义。他们不必进行转义,不过转义也是起作用的。
+ 例如,[abcd] 和[a-d]是一样的。他们都匹配"brisket"中的‘b’,也都匹配“city”中的‘c’。/[a-z.]+/ 和/[\w.]+/与字符串“test.i.ng”匹配。
[^xyz] +

一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符。你可以使用破折号(-)来指定一个字符范围。任何普通字符在这里都是起作用的。

+ +

例如,[^abc] 和 [^a-c] 是一样的。他们匹配"brisket"中的‘r’,也匹配“chop”中的‘h’。

+
[\b] +

匹配一个退格(U+0008)。(不要和\b混淆了。)

+
\b +

匹配一个词的边界。一个词的边界就是一个词不被另外一个“字”字符跟随的位置或者前面跟其他“字”字符的位置,例如在字母和空格之间。注意,匹配中不包括匹配的字边界。换句话说,一个匹配的词的边界的内容的长度是0。(不要和[\b]混淆了)

+ +

使用"moon"举例:
+ /\bm/匹配“moon”中的‘m’;
+ /oo\b/并不匹配"moon"中的'oo',因为'oo'被一个“字”字符'n'紧跟着。
+ /oon\b/匹配"moon"中的'oon',因为'oon'是这个字符串的结束部分。这样他没有被一个“字”字符紧跟着。
+ /\w\b\w/将不能匹配任何字符串,因为在一个单词中间的字符永远也不可能同时满足没有“字”字符跟随和有“字”字符跟随两种情况。

+ +
+

注意: JavaScript的正则表达式引擎将特定的字符集定义为“字”字符。不在该集合中的任何字符都被认为是一个断词。这组字符相当有限:它只包括大写和小写的罗马字母,十进制数字和下划线字符。不幸的是,重要的字符,例如“é”或“ü”,被视为断词。

+
+
\B +

匹配一个非单词边界。匹配如下几种情况:

+ +
    +
  • 字符串第一个字符为非“字”字符
  • +
  • 字符串最后一个字符为非“字”字符
  • +
  • 两个单词字符之间
  • +
  • 两个非单词字符之间
  • +
  • 空字符串
  • +
+ +

例如,/\B../匹配"noonday"中的'oo', 而/y\B../匹配"possibly yesterday"中的’yes‘

+
\cX +

当X是处于A到Z之间的字符的时候,匹配字符串中的一个控制符。

+ +

例如,/\cM/ 匹配字符串中的 control-M (U+000D)。

+
\d +

匹配一个数字等价于[0-9]

+ +

例如, /\d/ 或者 /[0-9]/ 匹配"B2 is the suite number."中的'2'。

+
\D +

匹配一个非数字字符等价于[^0-9]

+ +

例如, /\D/ 或者 /[^0-9]/ 匹配"B2 is the suite number."中的'B' 。

+
\f匹配一个换页符 (U+000C)。
\n匹配一个换行符 (U+000A)。
\r匹配一个回车符 (U+000D)。
\s +

匹配一个空白字符,包括空格、制表符、换页符和换行符。等价于[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]。

+ +

例如, /\s\w*/ 匹配"foo bar."中的' bar'。

+ +

经测试,\s不匹配"\u180e",在当前版本Chrome(v80.0.3987.122)和Firefox(76.0.1)控制台输入/\s/.test("\u180e")均返回false。

+
\S +

匹配一个非空白字符。等价于 [^ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]

+ +

例如,/\S\w*/ 匹配"foo bar."中的'foo'。

+
\t匹配一个水平制表符 (U+0009)。
\v匹配一个垂直制表符 (U+000B)。
\w +

匹配一个单字字符(字母、数字或者下划线)。等价于 [A-Za-z0-9_]

+ +

例如, /\w/ 匹配 "apple," 中的 'a',"$5.28,"中的 '5' 和 "3D." 中的 '3'。

+
\W +

匹配一个非单字字符。等价于 [^A-Za-z0-9_]

+ +

例如, /\W/ 或者 /[^A-Za-z0-9_]/ 匹配 "50%." 中的 '%'。

+
\n +

在正则表达式中,它返回最后的第n个子捕获匹配的子字符串(捕获的数目以左括号计数)。

+ +

比如 /apple(,)\sorange\1/ 匹配"apple, orange, cherry, peach."中的'apple, orange,' 。

+
\0匹配 NULL(U+0000)字符, 不要在这后面跟其它小数,因为 \0<digits> 是一个八进制转义序列。
\xhh匹配一个两位十六进制数(\x00-\xFF)表示的字符。
\uhhhh匹配一个四位十六进制数表示的 UTF-16 代码单元。
+

\u{hhhh}或\u{hhhhh}

+
(仅当设置了u标志时)匹配一个十六进制数表示的 Unicode 字符。
+ +

Escaping

+ +

如果你需要使用任何特殊字符的字面值(例如,搜索字符'*'),你必须通过在它前面放一个反斜杠来转义它。 例如,要搜索'a'后跟'*'后跟'b',你应该使用/a\*b/- 反斜杠“转义”字符'*',使其成为文字而非特殊符号。

+ +

类似地,如果您正在编写正则表达式文字并且需要匹配斜杠('/'),那么需要转义它(否则,斜杠是正则终止符)。 例如,要搜索字符串“/ example /”后跟一个或多个字母字符,您需要使用/\/example\/[a-z]+/i——每个斜杠之前使用反斜杠使它们成为普通字符。

+ +

要匹配文本符号反斜杠,您需要转义反斜杠。 例如,要匹配字符串“C:\”,其中“C”可以是任何字母,您将使用/[A-Z]:\\/ —— 第一个反斜杠转义后面的那个反斜杠,因此表达式搜索单个普通字符反斜杠。

+ +

如果将RegExp构造函数与字符串文字一起使用,请记住反斜杠是字符串文字中的转义,因此要在正则表达式中使用它,您需要在字符串文字级别转义它。 /a\*b/new RegExp("a\\*b")创建的表达式是相同的,搜索“a”后跟文字“*”后跟“b”。

+ +

将用户输入转义为正则表达式中的一个字面字符串, 可以通过简单的替换来实现:

+ +
function escapeRegExp(string) {
+  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+  //$&表示整个被匹配的字符串
+}
+ +

正则表达式后的"g"是一个表示全局搜索选项或标记,将在整个字符串查找并返回所有匹配结果。这将在下面的通过标志进行高级搜索详述。

+ +

为什么这个没有内建在JavaScript中?之前有计划在RegExp对象中添加一个Function,但在TC39中被否决了。

+ +

使用插入语

+ +

任何正则表达式的插入语都会使这部分匹配的副字符串被记忆。一旦被记忆,这个副字符串就可以被调用于其它用途,如同 使用括号的子字符串匹配之中所述。

+ +

比如, /Chapter (\d+)\.\d*/ 解释了额外转义的和特殊的字符,并说明了这部分pattern应该被记忆。它精确地匹配后面跟着一个以上数字字符的字符 'Chapter ' (\d 意为任何数字字符,+ 意为1次以上),跟着一个小数点(在这个字符中本身也是一个特殊字符;小数点前的 \ 意味着这个pattern必须寻找字面字符 '.'),跟着任何数字字符0次以上。 (\d 意为数字字符, * 意为0次以上)。另外,插入语也用来记忆第一个匹配的数字字符。

+ +

此模式可以匹配字符串"Open Chapter 4.3, paragraph 6",并且'4'将会被记住。此模式并不能匹配"Chapter 3 and 4",因为在这个字符串中'3'的后面没有点号'.'。

+ +

括号中的"?:",这种模式匹配的子字符串将不会被记住。比如,(?:\d+)匹配一次或多次数字字符,但是不能记住匹配的字符。

+ +

使用正则表达式

+ +

正则表达式可以被用于 RegExpexectest 方法以及 Stringmatchreplacesearchsplit 方法。这些方法在 JavaScript 手册中有详细的解释。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
使用正则表达式的方法
方法描述
{{jsxref("RegExp.exec", "exec")}}一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。
{{jsxref("RegExp.test", "test")}}一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。
{{jsxref("String.match", "match")}}一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。
{{jsxref("String.matchAll", "matchAll")}}一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。
{{jsxref("String.search", "search")}}一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。
{{jsxref("String.replace", "replace")}}一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。
{{jsxref("String.split", "split")}}一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法。
+ +

当你想要知道在一个字符串中的一个匹配是否被找到,你可以使用 test 或 search 方法;想得到更多的信息(但是比较慢)则可以使用 exec 或 match 方法。如果你使用exec 或 match 方法并且匹配成功了,那么这些方法将返回一个数组并且更新相关的正则表达式对象的属性和预定义的正则表达式对象(详见下)。如果匹配失败,那么 exec 方法返回 null(也就是false)。

+ +

在接下来的例子中,脚本将使用exec方法在一个字符串中查找一个匹配。

+ +
var myRe = /d(b+)d/g;
+var myArray = myRe.exec("cdbbdbsbz");
+
+ +

如果你不需要访问正则表达式的属性,这个脚本通过另一个方法来创建myArray:

+ +
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+// 和 "cdbbdbsbz".match(/d(b+)d/g); 相似。
+// 但是 "cdbbdbsbz".match(/d(b+)d/g) 输出数组 [ "dbbd" ],
+// 而 /d(b+)d/g.exec('cdbbdbsbz') 输出数组 [ "dbbd", "bb", index: 1, input: "cdbbdbsbz" ].
+
+
+ +

如果你想通过一个字符串构建正则表达式,那么这个脚本还有另一种方法:

+ +
var myRe = new RegExp("d(b+)d", "g");
+var myArray = myRe.exec("cdbbdbsbz");
+
+ +

通过这些脚本,匹配成功后将返回一个数组并且更新正则表达式的属性,如下表所示。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
正则表达式执行后的返回信息
对象属性或索引描述在例子中对应的值
myArray匹配到的字符串和所有被记住的子字符串。["dbbd", "bb"]
index在输入的字符串中匹配到的以0开始的索引值。1
input初始字符串。"cdbbdbsbz"
[0]最近一个匹配到的字符串。"dbbd"
myRelastIndex开始下一个匹配的起始索引值。(这个属性只有在使用g参数时可用在 通过参数进行高级搜索 一节有详细的描述.)5
source模式字面文本。在正则表达式创建时更新,不执行。"d(b+)d"
+ +

如这个例子中的第二种形式所示,你可以使用对象初始器创建一个正则表达式实例,但不分配给变量。如果你这样做,那么,每一次使用时都会创建一个新的正则表达式实例。因此,如果你不把正则表达式实例分配给一个变量,你以后将不能访问这个正则表达式实例的属性。例如,假如你有如下脚本:

+ +
var myRe = /d(b+)d/g;
+var myArray = myRe.exec("cdbbdbsbz");
+console.log("The value of lastIndex is " + myRe.lastIndex);
+
+ +

这个脚本输出如下:

+ +
The value of lastIndex is 5
+
+ +

然而,如果你有如下脚本:

+ +
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
+
+ +

它显示为:

+ +
The value of lastIndex is 0
+
+ +

当发生/d(b+)d/g使用两个不同状态的正则表达式对象,lastIndex属性会得到不同的值。如果你需要访问一个正则表达式的属性,则需要创建一个对象初始化生成器,你应该首先把它赋值给一个变量。

+ +

使用括号的子字符串匹配

+ +

一个正则表达式模式使用括号,将导致相应的子匹配被记住。例如,/a(b)c /可以匹配字符串“abc”,并且记得“b”。回调这些括号中匹配的子串,使用数组元素[1],……[n]。

+ +

使用括号匹配的子字符串的数量是无限的。返回的数组中保存所有被发现的子匹配。下面的例子说明了如何使用括号的子字符串匹配。

+ +

下面的脚本使用replace()方法来转换字符串中的单词。在匹配到的替换文本中,脚本使用替代的$ 1,$ 2表示第一个和第二个括号的子字符串匹配。

+ +
var re = /(\w+)\s(\w+)/;
+var str = "John Smith";
+var newstr = str.replace(re, "$2, $1");
+console.log(newstr);
+
+ +

这个表达式输出 "Smith, John"。

+ +

通过标志进行高级搜索

+ +

正则表达式有六个可选参数 (flags) 允许全局和不分大小写搜索等。这些参数既可以单独使用也能以任意顺序一起使用, 并且被包含在正则表达式实例中。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
正则表达式标志
标志描述
g全局搜索。
i不区分大小写搜索。
m多行搜索。
s允许 . 匹配换行符。
u使用unicode码的模式进行匹配。
y执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。
+ +

为了在正则表达式中包含标志,请使用以下语法:

+ +
var re = /pattern/flags;
+
+ +

或者

+ +
var re = new RegExp("pattern", "flags");
+
+ +

值得注意的是,标志是一个正则表达式的一部分,它们在接下来的时间将不能添加或删除。

+ +

例如,re = /\w+\s/g 将创建一个查找一个或多个字符后有一个空格的正则表达式,或者组合起来像此要求的字符串。

+ +
var re = /\w+\s/g;
+var str = "fee fi fo fum";
+var myArray = str.match(re);
+console.log(myArray);
+
+// ["fee ", "fi ", "fo "]
+
+ +

这段代码将输出 ["fee ", "fi ", "fo "]。在这个例子中,你可以将:

+ +
var re = /\w+\s/g;
+
+ +

替换成:

+ +
var re = new RegExp("\\w+\\s", "g");
+
+ +

并且能获取到相同的结果。

+ +

使用.exec()方法时,与'g'标志关联的行为是不同的。 (“class”和“argument”的作用相反:在.match()的情况下,字符串类(或数据类型)拥有该方法,而正则表达式只是一个参数,而在.exec()的情况下,它是拥有该方法的正则表达式,其中字符串是参数。对比str.match(re)re.exec(str) ), 'g'标志与.exec()方法一起使用获得迭代进展。

+ +
var xArray; while(xArray = re.exec(str)) console.log(xArray);
+// produces:
+// ["fee ", index: 0, input: "fee fi fo fum"]
+// ["fi ", index: 4, input: "fee fi fo fum"]
+// ["fo ", index: 7, input: "fee fi fo fum"]
+ +

m标志用于指定多行输入字符串应该被视为多个行。如果使用m标志,^和$匹配的开始或结束输入字符串中的每一行,而不是整个字符串的开始或结束。

+ +

例子

+ +

以下例子说明了一些正则表达式的用途。

+ +

改变输入字符串的顺序

+ +

以下例子解释了正则表达式的构成和 string.split() 以及 string.replace()的用途。它会整理一个只有粗略格式的含有全名(名字首先出现)的输入字符串,这个字符串被空格、换行符和一个分号分隔。最终,它会颠倒名字顺序(姓氏首先出现)和list的类型。

+ +
// 下面这个姓名字符串包含了多个空格和制表符,
+// 且在姓和名之间可能有多个空格和制表符。
+var names = "Orange Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ";
+
+var output = ["---------- Original String\n", names + "\n"];
+
+// 准备两个模式的正则表达式放进数组里。
+// 分割该字符串放进数组里。
+
+// 匹配模式:匹配一个分号及紧接其前后所有可能出现的连续的不可见符号。
+var pattern = /\s*;\s*/;
+
+// 把通过上述匹配模式分割的字符串放进一个叫做nameList的数组里面。
+var nameList = names.split(pattern);
+
+// 新建一个匹配模式:匹配一个或多个连续的不可见字符及其前后紧接着由
+// 一个或多个连续的基本拉丁字母表中的字母、数字和下划线组成的字符串
+// 用一对圆括号来捕获该模式中的一部分匹配结果。
+// 捕获的结果稍后会用到。
+pattern = /(\w+)\s+(\w+)/;
+
+// 新建一个数组 bySurnameList 用来临时存放正在处理的名字。
+var bySurnameList = [];
+
+// 输出 nameList 的元素并且把 nameList 里的名字
+// 用逗号接空格的模式把姓和名分割开来然后存放进数组 bySurnameList 中。
+//
+// 下面的这个替换方法把 nameList 里的元素用 $2, $1 的模式
+// (第二个捕获的匹配结果紧接着一个逗号一个空格然后紧接着第一个捕获的匹配结果)替换了
+// 变量 $1 和变量 $2 是上面所捕获的匹配结果。
+
+output.push("---------- After Split by Regular Expression");
+
+var i, len;
+for (i = 0, len = nameList.length; i < len; i++) {
+  output.push(nameList[i]);
+  bySurnameList[i] = nameList[i].replace(pattern, "$2, $1");
+}
+
+// 输出新的数组
+output.push("---------- Names Reversed");
+for (i = 0, len = bySurnameList.length; i < len; i++){
+  output.push(bySurnameList[i]);
+}
+
+// 根据姓来排序,然后输出排序后的数组。
+bySurnameList.sort();
+output.push("---------- Sorted");
+for (i = 0, len = bySurnameList.length; i < len; i++){
+  output.push(bySurnameList[i]);
+}
+
+output.push("---------- End");
+
+console.log(output.join("\n"));
+
+ +

用特殊字符检验输入

+ +

在以下例子中,我们期望用户输入一个电话号码。当用户点击“Check”按钮,我们的脚本开始检查这些数字是否合法。如果数字合法(匹配正则表达式所规定的字符序列),脚本显示一条感谢用户的信息并确认该数字。如果这串数字不合法,脚本提示用户电话号码不合法。.

+ +

包含非捕获括号 (?: 这个正则表达式寻找三个数字字符\d{3} 或者 | 一个左半括号\(跟着三位数字\d{3}, 跟着一个封闭括号 \), (结束非捕获括号 )), 后跟着一个短破折号或正斜杠或小数点,随后跟随三个数字字符,当记忆字符 ([-\/\.])捕获并记住,后面跟着三位小数 \d{3},再后面跟随记住的破折号、正斜杠或小数点 \1,最后跟着四位小数 \d{4}。

+ +

当用户按下 Enter 设置 RegExp.input,这些变化也能被激活。

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+    <meta http-equiv="Content-Script-Type" content="text/javascript">
+    <script type="text/javascript">
+      var re = /(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}/;
+      function testInfo(phoneInput) {
+        var OK = re.exec(phoneInput.value);
+        if (!OK)
+          window.alert(phoneInput.value + ' isn\'t a phone number with area code!');
+        else
+          window.alert('Thanks, your phone number is ' + OK[0]);
+      }
+    </script>
+  </head>
+  <body>
+    <p>Enter your phone number (with area code) and then click "Check".
+        <br>The expected format is like ###-###-####.</p>
+    <form action="#">
+      <input id="phone"><button onclick="testInfo(document.getElementById('phone'));">Check</button>
+    </form>
+  </body>
+</html>
+
+ +
{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html new file mode 100644 index 0000000000..0b0252022a --- /dev/null +++ b/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html @@ -0,0 +1,171 @@ +--- +title: Unicode property escapes +slug: Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes +translation_of: Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes +--- +

{{jsSidebar("JavaScript Guide")}}

+ +

Unicode property escapes 正则表达式 支持根据 Unicode 属性进行匹配,例如我们可以用它来匹配出表情、标点符号、字母(甚至适用特定语言或文字)等。同一符号可以拥有多种 Unicode 属性,属性则有 binary ("boolean-like") 和 non-binary 之分。

+ +
{{EmbedInteractiveExample("pages/js/regexp-unicode-property-escapes.html", "taller")}}
+ +
+

Note: 使用 Unicode 属性转义依靠 \u 标识\u 表示该字符串被视为一串 Unicode 代码点。参考 RegExp.prototype.nicode.

+
+ +
+

Note: 某些 Unicode 属性比字符类(如 \w 只匹配拉丁字母 a 到 z)包含更多的字符  ,但后者浏览器兼容性更好 (截至2020 一月).

+
+ +

句法

+ + + +
// Non-binary 属性
+\p{Unicode属性值}
+\p{Unicode属性名=Unicode属性值}
+
+// Binary and non-binary 属性
+\p{UnicodeBinary属性名}
+
+// \P 为 \p 取反
+\P{Unicode属性值}
+\P{UnicodeBinary属性名}
+
+ + + +

参考 PropertyValueAliases.txt 

+ +
+
UnicodeBinary属性名
+
Binary 属性名. E.g.: ASCIIAlpha, Math, DiacriticEmojiHex_DigitMath, White_space, 等. 另见 Unicode Data PropList.txt.
+
Unicode属性名
+
Non-binary 属性名:
+
Unicode属性值
+
很多值有同名或简写(e.g. 对应着 General_Category 属性名的属性值 Decimal_Number 可以写作 Nd, digit, 或 Decimal_Number). 大多数属性值的 Unicode属性名 和等号可以省去。如果想明确某 Unicode属性名,必须给出它的值。
+
+ +
+

Note: 因为可使用的属性和值太多,这里不一一赘述,仅提供几个例子。

+
+ +

基本原理

+ +

在 ES2018 之前,JavaScript 没有强有效的方式用匹配出不同文字(如马其顿语,希腊语,Georgian 等)或不同 属性名 (如 Emoji 等)的字符。另见 tc39 Proposal on Unicode Property Escapes.

+ +

例子

+ +

(一般类别)General categories

+ +

General categories 对 Unicode 字符进行分类,子类别用于精确定义类别。长名和简写的 Unicode 属性转义都可用.

+ +

它们可匹配字母、数字、符号、标点符号、空格等等。一般类别详见 the Unicode specification.

+ +
// finding all the letters of a text
+let story = "It’s the Cheshire Cat: now I shall have somebody to talk to.";
+
+// Most explicit form
+story.match(/\p{General_Category=Letter}/gu);
+
+// It is not mandatory to use the property name for General categories
+story.match(/\p{Letter}/gu);
+
+// This is equivalent (short alias):
+story.match(/\p{L}/gu);
+
+// This is also equivalent (conjunction of all the subcategories using short aliases)
+story.match(/\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}/gu);
+
+ +

文字(Script)和文字扩充(Script_Extensions)

+ +

某些语言使用不同的文字,如英语和西班牙语使用拉丁文,而阿拉伯语和俄语用阿拉伯文和俄文。Script 和 Script_Extensions Unicode 属性允许正则表达式根据字符所属的文字或该文字所属的文字扩充进行匹配。

+ +

比如,A 属于 拉丁文ε 属于希腊(Greek)文。

+ +
let mixedCharacters = "aεЛ";
+
+// Using the canonical "long" name of the script
+mixedCharacters.match(/\p{Script=Latin}/u); // a
+
+// Using a short alias for the script
+mixedCharacters.match(/\p{Script=Grek}/u); // ε
+
+// Using the short name Sc for the Script property
+mixedCharacters.match(/\p{Sc=Cyrillic}/u); // Л
+
+ +

详见 the Unicode specificationScripts table in the ECMAScript specification.

+ +

某字符用于多种文字时,Script 优先匹配最主要使用那个字符的文字。如果想要根据非主要的文字进行匹配,我们可以使用 Script_Extensions 属性 (简写为Scx).

+ +
// ٢ is the digit 2 in Arabic-Indic notation
+// while it is predominantly written within the Arabic script
+// it can also be written in the Thaana script
+
+"٢".match(/\p{Script=Thaana}/u);
+// null as Thaana is not the predominant script        super()
+
+"٢".match(/\p{Script_Extensions=Thaana}/u);
+// ["٢", index: 0, input: "٢", groups: undefined]
+
+ +

Unicode 属性转义 vs. 字符类

+ +

JavaScript 正则表达式可以使用 字符类 尤其是 \w 或 \d 匹配字母或数字,然而,这样的形式只匹配拉丁文字的字符 (换言之,a 到 z、 A 到 Z\w0 到 9 的 \d),见例子,这样的使用放到非拉丁文本中是有些蠢的。

+ +

Unicode 属性转义 categories 包含更多字符, \p{Letter} 或 \p{Number} 将会适用于任何文字。

+ +
// Trying to use ranges to avoid \w limitations:
+
+const nonEnglishText = "Приключения Алисы в Стране чудес";
+const regexpBMPWord = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
+// BMP goes through U+0000 to U+FFFF but space is U+0020
+
+console.table(nonEnglishText.match(regexpBMPWord));
+
+// Using Unicode property escapes instead
+const regexpUPE = /\p{L}+/gu;
+console.table(nonEnglishText.match(regexpUPE));
+
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-runtime-semantics-unicodematchproperty-p', 'RegExp: Unicode property escapes')}}
+ +

Browser compatibility

+ +

For browser compatibility information, check out the main Regular Expressions compatibility table.

+ +

See also

+ + diff --git "a/files/zh-cn/web/javascript/guide/regular_expressions/\351\207\217\350\257\215/index.html" "b/files/zh-cn/web/javascript/guide/regular_expressions/\351\207\217\350\257\215/index.html" new file mode 100644 index 0000000000..bcc2a35e13 --- /dev/null +++ "b/files/zh-cn/web/javascript/guide/regular_expressions/\351\207\217\350\257\215/index.html" @@ -0,0 +1,170 @@ +--- +title: 量词 +slug: Web/JavaScript/Guide/Regular_Expressions/量词 +translation_of: Web/JavaScript/Guide/Regular_Expressions/Quantifiers +--- +

{{jsSidebar("JavaScript Guide")}}

+ +

量词表示要匹配的字符或表达式的数量。

+ +
{{EmbedInteractiveExample("pages/js/regexp-quantifiers.html", "taller")}}
+ +

类型

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CharactersMeaning
x* +

将前面的项“x”匹配0次或更多次。例如,/bo*/匹配“A ghost booooed”中的“boooo”和“A bird warbled”中的“b”,但在“A goat grunt”中没有匹配。

+
x+ +

将前一项“x”匹配1次或更多次。等价于{1,}。例如,/a+/匹配“candy”中的“a”和“caaaaaaandy”中的“a”。

+
x? +

将前面的项“x”匹配0或1次。例如,/ e ?勒?/匹配angel中的el和angle中的le。

+ +

如果立即在任何量词*、+、?或{}之后使用,则使量词是非贪婪的(匹配最小次数),而不是默认的贪婪的(匹配最大次数)。

+
x{n} +

其中“n”是一个正整数,与前一项“x”的n次匹配。例如,/a{2}/ 不匹配“candy”中的“a”,但它匹配“caandy”中的所有“a”,以及“caaandy”中的前两个“a”。

+
x{n,} +

其中,“n”是一个正整数,与前一项“x”至少匹配“n”次。例如,/a{2,}/不匹配“candy”中的“a”,但匹配“caandy”和“caaaaaaandy”中的所有a。

+
x{n,m} +

其中,“n”是0或一个正整数,“m”是一个正整数,而m > n至少与前一项“x”匹配,最多与“m”匹配。例如,/a{1,3}/不匹配“cndy”中的“a”,“candy”中的“a”,“caandy”中的两个“a”,以及“caaaaaaandy”中的前三个“a”。注意,当匹配“caaaaaaandy”时,匹配的是“aaa”,即使原始字符串中有更多的“a”。

+
+

x*?
+ x+?
+ x??
+ x{n}?
+ x{n,}?
+ x{n,m}?

+
+

默认情况下,像 和 这样的量词是“贪婪的”,这意味着它们试图匹配尽可能多的字符串。?量词后面的字符使量词“非贪婪”:意思是它一旦找到匹配就会停止。例如,给定一个字符串“some <foo> <bar> new </bar> </foo> thing”:

+ +
    +
  • /<.*>/ will match "<foo> <bar> new </bar> </foo>"
  • +
  • /<.*?>/ will match "<foo>"
  • +
+
+ +

举例说明

+ +

重复模式

+ +
var wordEndingWithAs = /\w+a+/;
+var delicateMessage = "This is Spartaaaaaaa";
+
+console.table(delicateMessage.match(wordEndingWithAs)); // [ "Spartaaaaaaa" ]
+ +

计算字符集

+ +
var singleLetterWord = /\b\w\b/g;
+var notSoLongWord = /\b\w{1,6}\b/g;
+var loooongWord = /\b\w{13,}\b/g;
+
+var sentence = "Why do I have to learn multiplication table?";
+
+console.table(sentence.match(singleLetterWord)); // ["I"]
+console.table(sentence.match(notSoLongWord));    // [ "Why", "do", "I", "have", "to", "learn", "table" ]
+console.table(sentence.match(loooongWord));      // ["multiplication"]可选可选字符
+
+ +

 可选字符

+ +
var britishText = "He asked his neighbour a favour.";
+var americanText = "He asked his neighbor a favor.";
+
+var regexpEnding = /\w+ou?r/g;
+// \w+ One or several letters
+// o   followed by an "o",
+// u?  optionally followed by a "u"
+// r   followed by an "r"
+
+console.table(britishText.match(regexpEnding));
+// ["neighbour", "favour"]
+
+console.table(americanText.match(regexpEnding));
+// ["neighbor", "favor"]
+
+ +

贪婪 与 非贪婪的

+ +
var text = "I must be getting somewhere near the centre of the earth.";
+var greedyRegexp = /[\w ]+/;
+// [\w ]      a letter of the latin alphabet or a whitespace
+//      +     one or several times
+
+console.log(text.match(greedyRegexp)[0]);
+// "I must be getting somewhere near the centre of the earth"
+// almost all of the text matches (leaves out the dot character)
+
+var nonGreedyRegexp = /[\w ]+?/; // Notice the question mark
+console.log(text.match(nonGreedyRegexp));
+// "I"
+// The match is the smallest one possible
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-quantifier', 'RegExp: Quantifiers')}}
+ +

浏览器支持

+ +

For browser compatibility information, check out the main Regular Expressions compatibility table.

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/guide/text_formatting/index.html b/files/zh-cn/web/javascript/guide/text_formatting/index.html new file mode 100644 index 0000000000..71d93dfe78 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/text_formatting/index.html @@ -0,0 +1,252 @@ +--- +title: Text formatting +slug: Web/JavaScript/Guide/Text_formatting +tags: + - Guide + - JavaScript +translation_of: Web/JavaScript/Guide/Text_formatting +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
+ +

本章介绍在Javascript中如何使用字符串与文本内容。

+ +

字符串

+ +

JavaScript中的 {{Glossary("String")}} 类型用于表示文本型的数据. 它是由无符号整数值(16bit)作为元素而组成的集合. 字符串中的每个元素在字符串中占据一个位置. 第一个元素的index值是0, 下一个元素的index值是1, 以此类推. 字符串的长度就是字符串中所含的元素个数.你可以通过String字面值或者String对象两种方式创建一个字符串。

+ +

String字面量

+ +

可以使用单引号或双引号创建简单的字符串:

+ +
'foo'
+"bar"
+ +

可以使用转义序列来创建更复杂的字符串:

+ +

16进制转义序列

+ +

\x之后的数值将被认为是一个16进制数.

+ +
'\xA9' // "©"
+
+ +

Unicode转义序列

+ +

Unicode转义序列在\u之后需要至少4个字符.

+ +
'\u00A9' // "©"
+ +

Unicode字元逸出

+ +

这是ECMAScript 6中的新特性。有了Unicode字元逸出,任何字符都可以用16进制数转义, 这使得通过Unicode转义表示大于0x10FFFF的字符成为可能。使用简单的Unicode转义时通常需要分别写字符相应的两个部分(译注:大于0x10FFFF的字符需要拆分为相应的两个小于0x10FFFF的部分)来达到同样的效果。

+ +

请参阅 {{jsxref("String.fromCodePoint()")}} 或 {{jsxref("String.prototype.codePointAt()")}}。

+ +
'\u{2F804}'
+
+// the same with simple Unicode escapes
+'\uD87E\uDC04'
+ +

字符串对象

+ +

{{jsxref("String")}} 对象是对原始string类型的封装 .

+ +
const foo = new String('foo'); // 创建一个 String 对象
+console.log(foo); // 输出: [String: 'foo']
+typeof foo; // 返回 'object'
+ +

你可以在String字面值上使用String对象的任何方法—JavaScript自动把String字面值转换为一个临时的String对象, 然后调用其相应方法,最后丢弃此临时对象.在String字面值上也可以使用String.length属性.

+ +

除非必要, 应该尽量使用 String 字面值,因为String对象的某些行为可能并不与直觉一致。举例:

+ +
const firstString = '2 + 2'; //创建一个字符串字面量
+const secondString = new String('2 + 2'); // 创建一个字符串对象
+eval(firstString); // 返回数字 4
+eval(secondString); // 返回字符串 "2 + 2"
+ +

String 对象有一个属性 length,标识了字符串中 UTF-16 的码点个数。举例,下面的代码把 13 赋值给了helloLength,因为 "Hello, World!" 包含 13 个字符,每个字符用一个 UTF-16 码点表示。你可以通过数组的方式访问每一个码点,但你不能修改每个字符,因为字符串是不变的类数组对象: 

+ +
const hello = 'Hello, World!';
+const helloLength = hello.length;
+hello[0] = 'L'; // 无效,因为字符串是不变的
+hello[0]; // 返回 "H"
+ +

Characters whose Unicode scalar values are greater than U+FFFF (such as some rare Chinese/Japanese/Korean/Vietnamese characters and some emoji) are stored in UTF-16 with two surrogate code units each. For example, a string containing the single character U+1F600 "Emoji grinning face" will have length 2. Accessing the individual code units in such a string using brackets may have undesirable consequences such as the formation of strings with unmatched surrogate code units, in violation of the Unicode standard. (Examples should be added to this page after MDN bug 857438 is fixed.) See also {{jsxref("String.fromCodePoint()")}} or {{jsxref("String.prototype.codePointAt()")}}.

+ +

String对象有许多方法: 举例来说有些方法返回字符串本身的变体, 如 substringtoUpperCase.

+ +

下表总结了 {{jsxref("String")}} 对象的方法.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

String对象方法

+
方法描述
{{jsxref("String.charAt", "charAt")}}, {{jsxref("String.charCodeAt", "charCodeAt")}}, {{jsxref("String.codePointAt", "codePointAt")}}返回字符串指定位置的字符或者字符编码。
{{jsxref("String.indexOf", "indexOf")}}, {{jsxref("String.lastIndexOf", "lastIndexOf")}}分别返回字符串中指定子串的位置或最后位置。
{{jsxref("String.startsWith", "startsWith")}}, {{jsxref("String.endsWith", "endsWith")}}, {{jsxref("String.includes", "includes")}}返回字符串是否以指定字符串开始、结束或包含指定字符串。
{{jsxref("String.concat", "concat")}}连接两个字符串并返回新的字符串。
{{jsxref("String.fromCharCode", "fromCharCode")}}, {{jsxref("String.fromCodePoint", "fromCodePoint")}}从指定的Unicode值序列构造一个字符串。这是一个String类方法,不是实例方法。
{{jsxref("String.split", "split")}}通过将字符串分离成一个个子串来把一个String对象分裂到一个字符串数组中。
{{jsxref("String.slice", "slice")}}从一个字符串提取片段并作为新字符串返回。
{{jsxref("String.substring", "substring")}}, {{jsxref("String.substr", "substr")}}分别通过指定起始和结束位置,起始位置和长度来返回字符串的指定子集。
{{jsxref("String.match", "match")}}, {{jsxref("String.replace", "replace")}}, {{jsxref("String.search", "search")}}通过正则表达式来工作.
{{jsxref("String.toLowerCase", "toLowerCase")}}, {{jsxref("String.toUpperCase", "toUpperCase")}} +

分别返回字符串的小写表示和大写表示。

+
{{jsxref("String.normalize", "normalize")}}按照指定的一种 Unicode 正规形式将当前字符串正规化。
{{jsxref("String.repeat", "repeat")}}将字符串内容重复指定次数后返回。
{{jsxref("String.trim", "trim")}}去掉字符串开头和结尾的空白字符。
+ +

多行模板字符串

+ +

模板字符串是一种允许内嵌表达式的String字面值. 可以用它实现多行字符串或者字符串内插等特性.

+ +

模板字符串使用反勾号 (` `) (grave accent) 包裹内容而不是单引号或双引号. 模板字符串可以包含占位符. 占位符用美元符号和花括号标识 (${expression}).

+ +

多行

+ +

源代码中插入的任何新行开始字符都作为模板字符串的内容. 使用一般的字符串时, 为了创建多行的字符串不得不用如下语法:

+ +
console.log("string text line 1\n\
+string text line 2");
+// "string text line 1
+// string text line 2"
+ +

为了实现同样效果的多行字符串, 现在可以写成如下形式:

+ +
console.log(`string text line 1
+string text line 2`);
+// "string text line 1
+// string text line 2"
+ +

嵌入表达式

+ +

为了在一般的字符串中嵌入表达式, 需要使用如下语法:

+ +
const five = 5;
+const ten = 10;
+console.log('Fifteen is ' + (five + ten) + ' and not ' + (2 * five + ten) + '.');
+// "Fifteen is 15 and not 20."
+ +

现在, 使用模板字符串, 可以使用语法糖让类似功能的实现代码更具可读性:

+ +
const five = 5;
+const ten = 10;
+console.log(`Fifteen is ${five + ten} and not ${2 * five + ten}.`);
+// "Fifteen is 15 and not 20."
+ +

更多信息, 请阅读 JavaScript reference 中的 Template strings

+ +

国际化

+ +

{{jsxref("Intl")}} 对象是ECMAScript国际化API的命名空间, 它提供了语言敏感的字符串比较,数字格式化和日期时间格式化功能.  {{jsxref("Collator")}}, {{jsxref("NumberFormat")}}, 和 {{jsxref("DateTimeFormat")}} 对象的构造函数是Intl对象的属性.

+ +

日期和时间格式化

+ +

{{jsxref("DateTimeFormat")}} 对象在日期和时间的格式化方面很有用. 下面的代码把一个日期格式化为美式英语格式. (不同时区结果不同.)

+ +
const msPerDay = 24 * 60 * 60 * 1000;
+
+// July 17, 2014 00:00:00 UTC.
+const july172014 = new Date(msPerDay * (44 * 365 + 11 + 197));//2014-1970=44年
+//这样创建日期真是醉人。。。还要自己计算天数。。。11是闰年中多出的天数。。。
+//197是6×30+16(7月的16天)+3(3个大月)-2(2月少2天)
+
+const options = { year: "2-digit", month: "2-digit", day: "2-digit",
+                hour: "2-digit", minute: "2-digit", timeZoneName: "short" };
+const americanDateTime = new Intl.DateTimeFormat("en-US", options).format;
+
+console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT
+
+ +

数字格式化

+ +

{{jsxref("NumberFormat")}} 对象在数字的格式化方面很有用, 比如货币数量值.

+ +
var gasPrice = new Intl.NumberFormat("en-US",
+                        { style: "currency", currency: "USD",
+                          minimumFractionDigits: 3 });
+
+console.log(gasPrice.format(5.259)); // $5.259
+
+var hanDecimalRMBInChina = new Intl.NumberFormat("zh-CN-u-nu-hanidec",
+                        { style: "currency", currency: "CNY" });
+
+console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五
+
+ +

定序

+ +

{{jsxref("Collator")}} 对象在字符串比较和排序方面很有用.

+ +

举例, 德语中有两种不同的排序方式 电话本(phonebook) 和 字典(dictionary). 电话本排序强调发音, 比如在排序前 “ä”, “ö”等被扩展为 “ae”, “oe”等发音.

+ +
var names = ["Hochberg", "Hönigswald", "Holzman"];
+
+var germanPhonebook = new Intl.Collator("de-DE-u-co-phonebk");
+
+// as if sorting ["Hochberg", "Hoenigswald", "Holzman"]:
+console.log(names.sort(germanPhonebook.compare).join(", "));
+// logs "Hochberg, Hönigswald, Holzman"
+
+ +

有些德语词包含变音, 所以在字典中忽略变音进行排序是合理的 (除非待排序的单词只有变音部分不同: schon 先于 schön).

+ +
var germanDictionary = new Intl.Collator("de-DE-u-co-dict");
+
+// as if sorting ["Hochberg", "Honigswald", "Holzman"]:
+console.log(names.sort(germanDictionary.compare).join(", "));
+// logs "Hochberg, Holzman, Hönigswald"
+
+ +

关于{{jsxref("Intl")}} API的更多信息, 请参考 Introducing the JavaScript Internationalization API

+ +
{{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
diff --git a/files/zh-cn/web/javascript/guide/using_promises/index.html b/files/zh-cn/web/javascript/guide/using_promises/index.html new file mode 100644 index 0000000000..c714260d7f --- /dev/null +++ b/files/zh-cn/web/javascript/guide/using_promises/index.html @@ -0,0 +1,359 @@ +--- +title: 使用 Promise +slug: Web/JavaScript/Guide/Using_promises +tags: + - Guide + - JavaScript + - Promise + - 中级 + - 异步 + - 指南 +translation_of: Web/JavaScript/Guide/Using_promises +--- +
{{jsSidebar("JavaScript Guide")}}{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}
+ +

{{jsxref("Promise")}} 是一个对象,它代表了一个异步操作的最终完成或者失败。因为大多数人仅仅是使用已创建的 Promise 实例对象,所以本教程将首先说明怎样使用 Promise,再说明如何创建 Promise。

+ +

本质上 Promise 是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。

+ +

假设现在有一个名为 createAudioFileAsync() 的函数,它接收一些配置和两个回调函数,然后异步地生成音频文件。一个回调函数在文件成功创建时被调用,另一个则在出现异常时被调用。

+ +

以下为使用 createAudioFileAsync() 的示例:

+ +
// 成功的回调函数
+function successCallback(result) {
+  console.log("音频文件创建成功: " + result);
+}
+
+// 失败的回调函数
+function failureCallback(error) {
+  console.log("音频文件创建失败: " + error);
+}
+
+createAudioFileAsync(audioSettings, successCallback, failureCallback)
+ +

更现代的函数会返回一个 Promise 对象,使得你可以将你的回调函数绑定在该 Promise 上。

+ +

如果函数 createAudioFileAsync() 被重写为返回 Promise 的形式,那么我们可以像下面这样简单地调用它:

+ +
const promise = createAudioFileAsync(audioSettings);
+promise.then(successCallback, failureCallback);
+
+ +

或者简写为:

+ +
createAudioFileAsync(audioSettings).then(successCallback, failureCallback);
+
+ +

我们把这个称为 异步函数调用,这种形式有若干优点,下面我们将会逐一讨论。

+ +

约定

+ +

不同于“老式”的传入回调,在使用 Promise 时,会有以下约定:

+ + + +

Promise 很棒的一点就是链式调用chaining)。

+ +

链式调用

+ +

连续执行两个或者多个异步操作是一个常见的需求,在上一个操作执行成功之后,开始下一个的操作,并带着上一步操作所返回的结果。我们可以通过创造一个 Promise 链来实现这种需求。

+ +

见证奇迹的时刻:then() 函数会返回一个和原来不同的新的 Promise

+ +
const promise = doSomething();
+const promise2 = promise.then(successCallback, failureCallback);
+
+ +

或者

+ +
const promise2 = doSomething().then(successCallback, failureCallback);
+ +

promise2 不仅表示 doSomething() 函数的完成,也代表了你传入的 successCallback 或者 failureCallback 的完成,这两个函数也可以返回一个 Promise 对象,从而形成另一个异步操作,这样的话,在 promise2 上新增的回调函数会排在这个 Promise 对象的后面。

+ +

基本上,每一个 Promise 都代表了链中另一个异步过程的完成。

+ +

在过去,要想做多重的异步操作,会导致经典的回调地狱:

+ +
doSomething(function(result) {
+  doSomethingElse(result, function(newResult) {
+    doThirdThing(newResult, function(finalResult) {
+      console.log('Got the final result: ' + finalResult);
+    }, failureCallback);
+  }, failureCallback);
+}, failureCallback);
+
+ +

现在,我们可以把回调绑定到返回的 Promise 上,形成一个 Promise 链:

+ +
doSomething().then(function(result) {
+  return doSomethingElse(result);
+})
+.then(function(newResult) {
+  return doThirdThing(newResult);
+})
+.then(function(finalResult) {
+  console.log('Got the final result: ' + finalResult);
+})
+.catch(failureCallback);
+
+ +

then 里的参数是可选的,catch(failureCallback)then(null, failureCallback) 的缩略形式。如下所示,我们也可以用箭头函数来表示:

+ +
doSomething()
+.then(result => doSomethingElse(result))
+.then(newResult => doThirdThing(newResult))
+.then(finalResult => {
+  console.log(`Got the final result: ${finalResult}`);
+})
+.catch(failureCallback);
+
+ +

注意:一定要有返回值,否则,callback 将无法获取上一个 Promise 的结果。(如果使用箭头函数,() => x() => { return x; } 更简洁一些,但后一种保留 return 的写法才支持使用多个语句。)。

+ +

Catch 的后续链式操作

+ +

有可能会在一个回调失败之后继续使用链式操作,即,使用一个 catch,这对于在链式操作中抛出一个失败之后,再次进行新的操作会很有用。请阅读下面的例子:

+ +
new Promise((resolve, reject) => {
+    console.log('初始化');
+
+    resolve();
+})
+.then(() => {
+    throw new Error('有哪里不对了');
+
+    console.log('执行「这个」”');
+})
+.catch(() => {
+    console.log('执行「那个」');
+})
+.then(() => {
+    console.log('执行「这个」,无论前面发生了什么');
+});
+
+ +

输出结果如下:

+ +
初始化
+执行“那个”
+执行“这个”,无论前面发生了什么
+
+ +

注意:因为抛出了错误 有哪里不对了,所以前一个 执行「这个」 没有被输出。

+ +

错误传递

+ +

在之前的回调地狱示例中,你可能记得有 3 次 failureCallback 的调用,而在 Promise 链中只有尾部的一次调用。

+ +
doSomething()
+.then(result => doSomethingElse(result))
+.then(newResult => doThirdThing(newResult))
+.then(finalResult => console.log(`Got the final result: ${finalResult}`))
+.catch(failureCallback);
+
+
+ +

通常,一遇到异常抛出,浏览器就会顺着 Promise 链寻找下一个 onRejected 失败回调函数或者由 .catch() 指定的回调函数。这和以下同步代码的工作原理(执行过程)非常相似。

+ +
try {
+  let result = syncDoSomething();
+  let newResult = syncDoSomethingElse(result);
+  let finalResult = syncDoThirdThing(newResult);
+  console.log(`Got the final result: ${finalResult}`);
+} catch(error) {
+  failureCallback(error);
+}
+
+ +

在 ECMAScript 2017 标准的 async/await 语法糖中,这种异步代码的对称性得到了极致的体现:

+ +
async function foo() {
+  try {
+    const result = await doSomething();
+    const newResult = await doSomethingElse(result);
+    const finalResult = await doThirdThing(newResult);
+    console.log(`Got the final result: ${finalResult}`);
+  } catch(error) {
+    failureCallback(error);
+  }
+}
+ +

这个例子是在 Promise 的基础上构建的,例如,doSomething() 与之前的函数是相同的。你可以在这里阅读更多的与此语法相关的文章。

+ +

通过捕获所有的错误,甚至抛出异常和程序错误,Promise 解决了回调地狱的基本缺陷。这对于构建异步操作的基础功能而言是很有必要的。

+ +

Promise 拒绝事件

+ +

当 Promise 被拒绝时,会有下文所述的两个事件之一被派发到全局作用域(通常而言,就是{{domxref("window")}};如果是在 web worker 中使用的话,就是 {{domxref("Worker")}} 或者其他 worker-based 接口)。这两个事件如下所示:

+ +
+
{{domxref("Window.rejectionhandled_event", "rejectionhandled")}}
+
当 Promise 被拒绝、并且在 reject 函数处理该 rejection 之后会派发此事件。
+
{{domxref("Window.unhandledrejection_event", "unhandledrejection")}}
+
当 Promise 被拒绝,但没有提供 reject 函数来处理该 rejection 时,会派发此事件。
+
+ +

以上两种情况中,{{domxref("PromiseRejectionEvent")}} 事件都有两个属性,一个是 {{domxref("PromiseRejectionEvent.promise", "promise")}} 属性,该属性指向被驳回的 Promise,另一个是 {{domxref("PromiseRejectionEvent.reason", "reason")}} 属性,该属性用来说明 Promise 被驳回的原因。

+ +

因此,我们可以通过以上事件为 Promise 失败时提供补偿处理,也有利于调试 Promise 相关的问题。在每一个上下文中,该处理都是全局的,因此不管源码如何,所有的错误都会在同一个处理函数中被捕捉并处理。

+ +

一个特别有用的例子:当你使用 {{Glossary("Node.js")}} 时,有些依赖模块可能会有未被处理的 rejected promises,这些都会在运行时打印到控制台。你可以在自己的代码中捕捉这些信息,然后添加与 {{domxref("Window.unhandledrejection_event", "unhandledrejection")}} 相应的处理函数来做分析和处理,或只是为了让你的输出更整洁。举例如下:

+ +
window.addEventListener("unhandledrejection", event => {
+  /* 你可以在这里添加一些代码,以便检查
+     event.promise 中的 promise 和
+     event.reason 中的 rejection 原因 */
+
+  event.preventDefault();
+}, false);
+
+ +

调用 event 的 {{domxref("Event.preventDefault", "preventDefault()")}} 方法是为了告诉 JavaScript 引擎当 Promise 被拒绝时不要执行默认操作,默认操作一般会包含把错误打印到控制台,Node 就是如此的。

+ +

理想情况下,在忽略这些事件之前,我们应该检查所有被拒绝的 Promise,来确认这不是代码中的 bug。

+ +

在旧式回调 API 中创建 Promise

+ +

可以通过 Promise 的构造器从零开始创建 {{jsxref("Promise")}}。 这种方式(通过构造器的方式)应当只在封装旧 API 的时候用到。

+ +

理想状态下,所有的异步函数都已经返回 Promise 了。但有一些 API 仍然使用旧方式来传入的成功(或者失败)的回调。典型的例子就是 {{domxref("WindowTimers.setTimeout", "setTimeout()")}} 函数:

+ +
setTimeout(() => saySomething("10 seconds passed"), 10000);
+
+ +

混用旧式回调和 Promise 可能会造成运行时序问题。如果 saySomething 函数失败了,或者包含了编程错误,那就没有办法捕获它了。这得怪 setTimeout

+ +

幸运地是,我们可以用 Promise 来封装它。最好的做法是,将这些有问题的函数封装起来,留在底层,并且永远不要再直接调用它们:

+ +
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
+
+wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback);
+
+ +

通常,Promise 的构造器接收一个执行函数(executor),我们可以在这个执行函数里手动地 resolve 和 reject 一个 Promise。既然 setTimeout 并不会真的执行失败,那么我们可以在这种情况下忽略 reject。

+ +

组合

+ +

{{jsxref("Promise.resolve()")}} 和 {{jsxref("Promise.reject()")}} 是手动创建一个已经 resolve 或者 reject 的 Promise 快捷方法。它们有时很有用。

+ +

{{jsxref("Promise.all()")}} 和 {{jsxref("Promise.race()")}} 是并行运行异步操作的两个组合式工具。

+ +

我们可以发起并行操作,然后等多个操作全部结束后进行下一步操作,如下:

+ +
Promise.all([func1(), func2(), func3()])
+.then(([result1, result2, result3]) => { /* use result1, result2 and result3 */ });
+ +

可以使用一些聪明的 JavaScript 写法实现时序组合:

+ +
[func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve())
+.then(result3 => { /* use result3 */ });
+ +

通常,我们递归调用一个由异步函数组成的数组时,相当于一个 Promise 链:

+ +
Promise.resolve().then(func1).then(func2).then(func3);
+ +

我们也可以写成可复用的函数形式,这在函数式编程中极为普遍:

+ +
const applyAsync = (acc,val) => acc.then(val);
+const composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));
+
+ +

composeAsync() 函数将会接受任意数量的函数作为其参数,并返回一个新的函数,该函数接受一个通过 composition pipeline 传入的初始值。这对我们来说非常有益,因为任一函数可以是异步或同步的,它们能被保证按顺序执行:

+ +
const transformData = composeAsync(func1, func2, func3);
+const result3 = transformData(data);
+
+ +

在 ECMAScript 2017 标准中, 时序组合可以通过使用 async/await 而变得更简单:

+ +
let result;
+for (const f of [func1, func2, func3]) {
+  result = await f(result);
+}
+/* use last result (i.e. result3) */
+ +

时序

+ +

为了避免意外,即使是一个已经变成 resolve 状态的 Promise,传递给 then() 的函数也总是会被异步调用:

+ +
Promise.resolve().then(() => console.log(2));
+console.log(1); // 1, 2
+
+ +

传递到 then() 中的函数被置入到一个微任务队列中,而不是立即执行,这意味着它是在 JavaScript 事件队列的所有运行时结束了,且事件队列被清空之后,才开始执行:

+ +
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
+
+wait().then(() => console.log(4));
+Promise.resolve().then(() => console.log(2)).then(() => console.log(3));
+console.log(1); // 1, 2, 3, 4
+ +

嵌套

+ +

简便的 Promise 链式编程最好保持扁平化,不要嵌套 Promise,因为嵌套经常会是粗心导致的。可查阅下一节的常见错误中的例子。

+ +

嵌套 Promise 是一种可以限制 catch 语句的作用域的控制结构写法。明确来说,嵌套的 catch 仅捕捉在其之前同时还必须是其作用域的 failureres,而捕捉不到在其链式以外或者其嵌套域以外的 error。如果使用正确,那么可以实现高精度的错误修复。

+ +
doSomethingCritical()
+.then(result => doSomethingOptional()
+  .then(optionalResult => doSomethingExtraNice(optionalResult))
+  .catch(e => {console.log(e.message)})) // 即使有异常也会忽略,继续运行;(最后会输出)
+.then(() => moreCriticalStuff())
+.catch(e => console.log("Critical failure: " + e.message));// 没有输出
+ +

注意,有些代码步骤是嵌套的,而不是一个简单的纯链式,这些语句前与后都被括号 () 包裹着。

+ +

这个内部的 catch  语句仅能捕获到 doSomethingOptional()doSomethingExtraNice() 的失败,之后就恢复到moreCriticalStuff() 的运行。重要提醒:如果 doSomethingCritical() 失败,这个错误仅会被最后的(外部)catch 语句捕获到。

+ +

常见错误

+ +

在编写 Promise 链时,需要注意以下示例中展示的几个错误:

+ +
// 错误示例,包含 3 个问题!
+
+doSomething().then(function(result) {
+  doSomethingElse(result) // 没有返回 Promise 以及没有必要的嵌套 Promise
+  .then(newResult => doThirdThing(newResult));
+}).then(() => doFourthThing());
+// 最后,是没有使用 catch 终止 Promise 调用链,可能导致没有捕获的异常
+ +

第一个错误是没有正确地将事物相连接。当我们创建新 Promise 但忘记返回它时,会发生这种情况。因此,链条被打破,或者更确切地说,我们有两个独立的链条竞争(同时在执行两个异步而非一个一个的执行)。这意味着 doFourthThing() 不会等待 doSomethingElse()doThirdThing() 完成,并且将与它们并行运行,可能是无意的。单独的链也有单独的错误处理,导致未捕获的错误。

+ +

第二个错误是不必要地嵌套,实现第一个错误。嵌套还限制了内部错误处理程序的范围,如果是非预期的,可能会导致未捕获的错误。其中一个变体是 Promise 构造函数反模式,它结合了 Promise 构造函数的多余使用和嵌套。

+ +

第三个错误是忘记用 catch 终止链。这导致在大多数浏览器中不能终止的 Promise 链里的 rejection。

+ +

一个好的经验法则是总是返回或终止 Promise 链,并且一旦你得到一个新的 Promise,返回它。下面是修改后的平面化的代码:

+ +
doSomething()
+.then(function(result) {
+  return doSomethingElse(result);
+})
+.then(newResult => doThirdThing(newResult))
+.then(() => doFourthThing())
+.catch(error => console.log(error));
+ +

注意:() => x() => { return x; } 的简写。

+ +

上述代码的写法就是具有适当错误处理的简单明确的链式写法。

+ +

使用 async/await 可以解决以上大多数错误,使用 async/await 时,最常见的语法错误就是忘记了 await 关键字。

+ +

参见

+ + + +

{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}

diff --git a/files/zh-cn/web/javascript/guide/working_with_objects/index.html b/files/zh-cn/web/javascript/guide/working_with_objects/index.html new file mode 100644 index 0000000000..eb65155228 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/working_with_objects/index.html @@ -0,0 +1,522 @@ +--- +title: 使用对象 +slug: Web/JavaScript/Guide/Working_with_Objects +tags: + - JavaScript + - 初学者 + - 基本语法 + - 教程 + - 文档 + - 比较对象 +translation_of: Web/JavaScript/Guide/Working_with_Objects +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}
+ +

JavaScript 的设计是一个简单的基于对象的范式。一个对象就是一系列属性的集合,一个属性包含一个名和一个值。一个属性的值可以是函数,这种情况下属性也被称为方法。除了浏览器里面预定义的那些对象之外,你也可以定义你自己的对象。本章节讲述了怎么使用对象、属性、函数和方法,怎样实现自定义对象。

+ +

对象概述

+ +

javascript 中的对象(物体),和其它编程语言中的对象一样,可以比照现实生活中的对象(物体)来理解它。 javascript 中对象(物体)的概念可以比照着现实生活中实实在在的物体来理解。

+ +

在javascript中,一个对象可以是一个单独的拥有属性和类型的实体。我们拿它和一个杯子做下类比。一个杯子是一个对象(物体),拥有属性。杯子有颜色,图案,重量,由什么材质构成等等。同样,javascript对象也有属性来定义它的特征。

+ +

对象和属性

+ +

一个 javascript 对象有很多属性。一个对象的属性可以被解释成一个附加到对象上的变量。对象的属性和普通的 javascript 变量基本没什么区别,仅仅是属性属于某个对象。属性定义了对象的特征(译注:动态语言面向对象的鸭子类型)。你可以通过点符号来访问一个对象的属性。

+ +
+
objectName.propertyName
+
+
+ +

和其他 javascript 变量一样,对象的名字(可以是普通的变量)和属性的名字都是大小写敏感的。你可以在定义一个属性的时候就给它赋值。例如,我们创建一个myCar的对象然后给他三个属性,make,model,year。具体如下所示:

+ +
var myCar = new Object();
+myCar.make = "Ford";
+myCar.model = "Mustang";
+myCar.year = 1969; 
+ +

对象中未赋值的属性的值为{{jsxref("undefined")}}(而不是{{jsxref("null")}})。

+ +
myCar.noProperty; // undefined
+
+ +

JavaScript 对象的属性也可以通过方括号访问或者设置(更多信息查看 property accessors). 对象有时也被叫作关联数组, 因为每个属性都有一个用于访问它的字符串值。例如,你可以按如下方式访问 myCar 对象的属性:

+ +
myCar["make"] = "Ford";
+myCar["model"] = "Mustang";
+myCar["year"] = 1969;
+
+ +

一个对象的属性名可以是任何有效的 JavaScript 字符串,或者可以被转换为字符串的任何类型,包括空字符串。然而,一个属性的名称如果不是一个有效的 JavaScript 标识符(例如,一个由空格或连字符,或者以数字开头的属性名),就只能通过方括号标记访问。这个标记法在属性名称是动态判定(属性名只有到运行时才能判定)时非常有用。例如:

+ +
// 同时创建四个变量,用逗号分隔
+var myObj = new Object(),
+    str = "myString",
+    rand = Math.random(),
+    obj = new Object();
+
+myObj.type              = "Dot syntax";
+myObj["date created"]   = "String with space";
+myObj[str]              = "String value";
+myObj[rand]             = "Random Number";
+myObj[obj]              = "Object";
+myObj[""]               = "Even an empty string";
+
+console.log(myObj);
+
+ +

请注意,方括号中的所有键都将转换为字符串类型,因为JavaScript中的对象只能使用String类型作为键类型。 例如,在上面的代码中,当将键obj添加到myObj时,JavaScript将调用obj.toString()方法,并将此结果字符串用作新键。

+ +

你也可以通过存储在变量中的字符串来访问属性:

+ +
+
var propertyName = "make";
+myCar[propertyName] = "Ford";
+
+propertyName = "model";
+myCar[propertyName] = "Mustang";
+
+
+ +

你可以在  for...in 语句中使用方括号标记以枚举一个对象的所有属性。为了展示它如何工作,下面的函数当你将对象及其名称作为参数传入时,显示对象的属性:

+ +
function showProps(obj, objName) {
+  var result = "";
+  for (var i in obj) {
+    if (obj.hasOwnProperty(i)) {
+        result += objName + "." + i + " = " + obj[i] + "\n";
+    }
+  }
+  return result;
+}
+
+ +

因而,对于函数调用 showProps(myCar, "myCar") 将返回以下值:

+ +
myCar.make = Ford
+myCar.model = Mustang
+myCar.year = 1969
+
+ +

枚举一个对象的所有属性

+ +

从 ECMAScript 5 开始,有三种原生的方法用于列出或枚举对象的属性:

+ + + +

在 ECMAScript 5 之前,没有原生的方法枚举一个对象的所有属性。然而,可以通过以下函数完成:

+ +
function listAllProperties(o){
+	var objectToInspect;
+	var result = [];
+
+	for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)){
+		result = result.concat(Object.getOwnPropertyNames(objectToInspect));
+	}
+
+	return result;
+}
+
+ +

这在展示 “隐藏”(在原型中的不能通过对象访问的属性,因为另一个同名的属性存在于原型链的早期)的属性时很有用。如果只想列出可访问的属性,那么只需要去除数组中的重复元素即可。

+ +

创建新对象

+ +

JavaScript 拥有一系列预定义的对象。另外,你可以创建你自己的对象。从  JavaScript 1.2 之后,你可以通过对象初始化器(Object Initializer)创建对象。或者你可以创建一个构造函数并使用该函数和 new 操作符初始化对象。

+ +

使用对象初始化器

+ +

除了通过构造函数创建对象之外,你也可以通过对象初始化器创建对象。使用对象初始化器也被称作通过字面值创建对象。对象初始化器与 C++ 术语相一致。

+ +

通过对象初始化器创建对象的语法如下:

+ +
var obj = { property_1:   value_1,   // property_# 可以是一个标识符...
+            2:            value_2,   // 或一个数字...
+           ["property" +3]: value_3,  //  或一个可计算的key...
+            // ...,
+            "property n": value_n }; // 或一个字符串
+
+ + + +

这里 obj 是新对象的名称,每一个 property_i 是一个标识符(可以是一个名称、数字或字符串字面量),并且每个 value_i 是一个其值将被赋予 property_i 的表达式。obj 与赋值是可选的;如果你不需要在其他地方引用对象,你就不需要将它赋给一个变量。(注意在接受一条语句的地方,你可能需要将对象字面量括在括号里,从而避免将字面量与块语句相混淆)

+ +

如果一个对象是通过在顶级脚本的对象初始化器创建的,则 JavaScript 在每次遇到包含该对象字面量的表达式时都会创建对象。同样的,在函数中的初始化器在每次函数调用时也会被创建。

+ +

下面的语句只有当 cond 表达式的值为 true 时创建对象并将其赋给变量 x

+ +
if (cond) var x = {hi: "there"};
+
+ +

下例创建了有三个属性的 myHonda 对象。注意它的 engine 属性也是一个拥有自己属性的对象。

+ +
var myHonda = {color: "red", wheels: 4, engine: {cylinders: 4, size: 2.2}};
+
+ +

你也可以用对象初始化器来创建数组。参见 {{ web.link("Values%2C_variables%2C_and_literals#Array_literals", "array literals") }}.

+ +

在 JavaScript 1.1 及更早版本中,你不能使用对象初始化器。你只能通过使用构造函数或其他对象的函数来创建对象。参见 {{ anch("使用构造函数") }}.

+ +

使用构造函数

+ +

作为另一种方式,你可以通过两步来创建对象:

+ +
    +
  1. 通过创建一个构造函数来定义对象的类型。首字母大写是非常普遍而且很恰当的惯用法。
  2. +
  3. 通过 new 创建对象实例。
  4. +
+ +

为了定义对象类型,为对象类型创建一个函数以声明类型的名称、属性和方法。例如,你想为汽车创建一个类型,并且将这类对象称为 car ,并且拥有属性 make, model, 和 year,你可以创建如下的函数:

+ +
function Car(make, model, year) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+}
+
+ +

注意通过使用 this 将传入函数的值赋给对象的属性。

+ +

现在你可以象这样创建一个 mycar 对象:

+ +
var mycar = new Car("Eagle", "Talon TSi", 1993);
+
+ +

该创建了 mycar 并且将指定的值赋给它的属性。因而 mycar.make 的值是字符串 "Eagle", mycar.year 的值是整数 1993,依此类推。

+ +

你可以通过调用 new 创建任意数量的 car 对象。例如:

+ +
var kenscar = new Car("Nissan", "300ZX", 1992);
+var vpgscar = new Car("Mazda", "Miata", 1990);
+
+ +

一个对象的属性值可以是另一个对象。例如,假设你按如下方式定义了 person 对象:

+ +
function Person(name, age, sex) {
+  this.name = name;
+  this.age = age;
+  this.sex = sex;
+}
+
+ +

然后按如下方式创建了两个 person 实例:

+ +
var rand = new Person("Rand McKinnon", 33, "M");
+var ken = new Person("Ken Jones", 39, "M");
+
+ +

那么,你可以重写 car 的定义以包含一个拥有它的 owner 属性,如:

+ +
function Car(make, model, year, owner) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+  this.owner = owner;
+}
+
+ +

你可以按如下方式创建新对象:

+ +
var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
+var car2 = new Car("Nissan", "300ZX", 1992, ken);
+
+ +

注意在创建新对象时,上面的语句将 randken 作为 owner 的参数值,而不是传入字符串字面量或整数值。接下来你如果想找出 car2 的拥有者的姓名,你可以访问如下属性:

+ +
car2.owner.name
+
+ +

注意你总是可以为之前定义的对象增加新的属性。例如,语句

+ +
car1.color = "black";
+
+ +

car1 增加了 color 属性,并将其值设为 "black." 然而,这并不影响其他的对象。想要为某个类型的所有对象增加新属性,你必须将属性加入到 car 对象类型的定义中。

+ +

使用 Object.create 方法

+ +

对象也可以用 {{jsxref("Object.create()")}} 方法创建。该方法非常有用,因为它允许你为创建的对象选择一个原型对象,而不用定义构造函数。

+ +
// Animal properties and method encapsulation
+var Animal = {
+  type: "Invertebrates", // 属性默认值
+  displayType : function() {  // 用于显示type属性的方法
+    console.log(this.type);
+  }
+}
+
+// 创建一种新的动物——animal1
+var animal1 = Object.create(Animal);
+animal1.displayType(); // Output:Invertebrates
+
+// 创建一种新的动物——Fishes
+var fish = Object.create(Animal);
+fish.type = "Fishes";
+fish.displayType(); // Output:Fishes
+
+ +

该函数更多的信息及详细用法,参见 {{ web.link("/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/create", "Object.create method") }}

+ +

继承

+ +

所有的 JavaScript 对象至少继承于一个对象。被继承的对象被称作原型,并且继承的属性可通过构造函数的 prototype 对象找到。查看更多详细 Inheritance and the prototype chain

+ +

对象属性索引

+ +

在 JavaScript 1.0 中,你可以通过名称或序号访问一个属性。但是在 JavaScript 1.1 及之后版本中,如果你最初使用名称定义了一个属性,则你必须通过名称来访问它;而如果你最初使用序号来定义一个属性,则你必须通过索引来访问它。

+ +

这个限制发生在你通过构造函数创建一个对象和它的属性(就象我们之前通过 Car 对象类型所做的那样)并且显式地定义了单独的属性(如 myCar.color = "red")之时。如果你最初使用索引定义了一个对象属性,例如 myCar[5] = "25",则你只可能通过 myCar[5] 引用它。

+ +

这条规则的例外是从与HTML对应的对象,例如 forms 数组。对于这些数组的元素,你总是既可以通过其序号(依据其在文档中出现的顺序),也可以按照其名称(如果有的话)访问它。举例而言,如果文档中的第二个 <form> 标签有一个 NAME 属性且值为 "myForm",访问该 form 的方式可以是 document.forms[1],document.forms["myForm"]或 document.myForm。

+ +

为对象类型定义属性

+ +

你可以通过 prototype 属性为之前定义的对象类型增加属性。这为该类型的所有对象,而不是仅仅一个对象增加了一个属性。下面的代码为所有类型为 car 的对象增加了 color 属性,然后为对象 car1color 属性赋值:

+ +
Car.prototype.color = null;
+car1.color = "black";
+
+ +

参见 JavaScript Reference 中 Function 对象的 prototype 属性 。

+ +

定义方法

+ +

一个方法 是关联到某个对象的函数,或者简单地说,一个方法是一个值为某个函数的对象属性。定义方法就像定义普通的函数,除了它们必须被赋给对象的某个属性。查看 method definitions了解更多详情例如:

+ +
objectName.methodname = function_name;
+
+var myObj = {
+  myMethod: function(params) {
+    // ...do something
+  }
+
+  // 或者 这样写也可以
+
+  myOtherMethod(params) {
+    // ...do something else
+  }
+};
+
+ +

这里 objectName 是一个已经存在的对象,methodname 是方法的名称,而 function_name 是函数的名称。

+ +

你可以在对象的上下文中象这样调用方法:

+ +
object.methodname(params);
+
+ +

你可以在对象的构造函数中包含方法定义来为某个对象类型定义方法。例如,你可以为之前定义的 car 对象定义一个函数格式化并显示其属性:

+ +
function displayCar() {
+  var result = `A Beautiful ${this.year} ${this.make} ${this.model}`;
+  pretty_print(result);
+}
+
+ +

这里 pretty_print 是一个显示横线和一个字符串的函数。注意使用 this 指代方法所属的对象。

+ +

你可以在对象定义中通过增加下述语句将这个函数变成 Car 的方法:

+ +
this.displayCar = displayCar;
+
+ +

因此,Car 的完整定义看上去将是:

+ +
function Car(make, model, year, owner) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+  this.owner = owner;
+  this.displayCar = displayCar;
+}
+
+ +

然后你可以按如下方式为每个对象调用 displayCar 方法:

+ +
car1.displayCar();
+car2.displayCar();
+
+ + + +

通过 this 引用对象

+ + + +

JavaScript 有一个特殊的关键字 this,它可以在方法中使用以指代当前对象。例如,假设你有一个名为 validate 的函数,它根据给出的最大与最小值检查某个对象的 value 属性:

+ +
function validate(obj, lowval, hival) {
+  if ((obj.value < lowval) || (obj.value > hival)) {
+    alert("Invalid Value!");
+  }
+}
+
+ +

然后,你可以在每个元素的 onchange 事件处理器中调用 validate,并通过 this 传入相应元素,代码如下:

+ +
<input type="text" name="age" size="3"
+  onChange="validate(this, 18, 99)">
+
+ +

总的说来, this 在一个方法中指调用的对象。

+ +

当与 form 属性一起使用时,this 可以指代当前对象的父窗体。在下面的例子中,窗体 myForm 包含一个 Text 对象和一个按钮,当用户点击按键,Text 对象的值被设为窗体的名称。按钮的 onclick 事件处理器使用 this.form 以指代其父窗体,即 myForm

+ +
<form name="myForm">
+<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
+<p><input name="button1" type="button" value="Show Form Name"
+     onclick="this.form.text1.value = this.form.name">
+</p>
+</form>
+ +

定义 getters 与 setters

+ +

一个 getter 是一个获取某个特定属性的值的方法。一个  setter 是一个设定某个属性的值的方法。你可以为预定义的或用户定义的对象定义 getter 和 setter 以支持新增的属性。定义 getter 和 setter 的语法采用对象字面量语法。

+ +

下面例子描述了getters 和 setters 是如何为用户定义的对象 o 工作的。

+ +
var o = {
+  a: 7,
+  get b() {
+    return this.a + 1;
+  },
+  set c(x) {
+    this.a = x / 2
+  }
+};
+
+console.log(o.a); // 7
+console.log(o.b); // 8
+o.c = 50;
+console.log(o.a); // 25
+ +

o 对象的属性如下:

+ + + +

请注意在一个对象字面量语法中定义getter和setter使用"[gs]et property()"的方式(相比较于__define[GS]etter__)时,并不是获取和设置某个属性自身,容易让人误以为是"[gs]et propertyName(){ }"这样错误的使用方法。定义一个getter或setter函数使用语法"[gs]et property()",定义一个已经声明的函数作为的getter和setter方法,使用Object.defineProperty(或者 Object.prototype.__defineGetter__ 旧语法回退)

+ +

下面这个例子展示使用getter和setter方法扩展 {{jsxref("Date")}}原型,为预定义好的Date类添加一个year的属性。定义属性year的getter和setter方法用到了Date类中已存在的getFullYear和setFullYear方法。

+ +

定义属性year的getter和setter:

+ +
var d = Date.prototype;
+Object.defineProperty(d, "year", {
+  get: function() { return this.getFullYear() },
+  set: function(y) { this.setFullYear(y) }
+});
+
+ +

通过一个Date对象使用getter和setter:

+ +
var now = new Date();
+console.log(now.year); // 2000
+now.year = 2001; // 987617605170
+console.log(now);
+// Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
+
+ +

原则上,getter 和 setter 既可以:

+ + + +

当使用 使用对象初始化器 的方式定义getter和setter时,只需要在getter方法前加get,在setter方法前加set,当然,getter方法必须是无参数的,setter方法只接受一个参数(设置为新值),例如:

+ +
var o = {
+  a: 7,
+  get b() { return this.a + 1; },
+  set c(x) { this.a = x / 2; }
+};
+
+ +

使用Object.defineProperties的方法,同样也可以对一个已创建的对象在任何时候为其添加getter或setter方法。这个方法的第一个参数是你想定义getter或setter方法的对象,第二个参数是一个对象,这个对象的属性名用作getter或setter的名字,属性名对应的属性值用作定义getter或setter方法的函数,下面是一个例子定义了和前面例子一样的getter和setter方法:

+ +
var o = { a:0 }
+
+Object.defineProperties(o, {
+    "b": { get: function () { return this.a + 1; } },
+    "c": { set: function (x) { this.a = x / 2; } }
+});
+
+o.c = 10 // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
+console.log(o.b) // Runs the getter, which yields a + 1 or 6
+
+ +

这两种定义方式的选择取决于你的编程风格和手头的工作量。当你定义一个原型准备进行初始化时,可以选择第一种方式,这种方式更简洁和自然。但是,当你需要添加getter和setter方法 —— 因为并没有编写原型或者特定的对象 ——使用第二种方式更好。第二种方式可能更能表现JavaScript语法的动态特性——但也会使代码变得难以阅读和理解。

+ +

删除属性

+ +

你可以用 delete 操作符删除一个不是继承而来的属性。下面的例子说明如何删除一个属性:

+ +
//Creates a new object, myobj, with two properties, a and b.
+var myobj = new Object;
+myobj.a = 5;
+myobj.b = 12;
+
+//Removes the a property, leaving myobj with only the b property.
+delete myobj.a;
+
+ +

如果一个全局变量不是用 var 关键字声明的话,你也可以用 delete 删除它:

+ +
g = 17;
+delete g;
+
+ +

参见{{ web.link("Expressions_and_operators#delete", "delete") }} 以获取更多信息。

+ +

比较对象

+ +

在 JavaScript 中 objects 是一种引用类型。两个独立声明的对象永远也不会相等,即使他们有相同的属性,只有在比较一个对象和这个对象的引用时,才会返回true.

+ +
// 两个变量, 两个具有同样的属性、但不相同的对象
+var fruit = {name: "apple"};
+var fruitbear = {name: "apple"};
+
+fruit == fruitbear // return false
+fruit === fruitbear // return false
+
+ +
+

注意: "===" 运算符用来检查数值是否相等: 1 === "1"返回false,而1 == "1" 返回true

+
+ +
// 两个变量, 同一个对象
+var fruit = {name: "apple"};
+var fruitbear = fruit;  // 将fruit的对象引用(reference)赋值给 fruitbear
+                        // 也称为将fruitbear“指向”fruit对象
+// fruit与fruitbear都指向同样的对象
+fruit == fruitbear // return true
+fruit === fruitbear // return true
+ +

了解更多关于比较操作符的用法,查看 Comparison operators.

+ +

附加参考

+ + + + + +

{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}

+ +
diff --git a/files/zh-cn/web/javascript/index.html b/files/zh-cn/web/javascript/index.html new file mode 100644 index 0000000000..5c06b803ab --- /dev/null +++ b/files/zh-cn/web/javascript/index.html @@ -0,0 +1,129 @@ +--- +title: JavaScript +slug: Web/JavaScript +tags: + - JavaScript + - Landing + - Learn + - priority +translation_of: Web/JavaScript +--- +
{{JsSidebar()}}
+ +
+

JavaScript ( JS ) 是一种具有{{Glossary("First-class Function", "函数优先")}}的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web 页面的脚本语言而出名的,但是它也被用到了很多非浏览器环境中,例如 Node.js、 Apache CouchDB 和 Adobe Acrobat。JavaScript 是一种{{Glossary("Prototype-based_programming", "基于原型编程")}}、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格。了解更多 JavaScript

+
+ +

本部分将专注于 JavaScript 语言本身,而非局限于网页或其他限制环境。想要了解网页有关的 {{Glossary("API","APIs")}} ,请参考 Web APIs 以及 DOM

+ +

JavaScript 的标准是 ECMAScript 。截至 2012 年,所有的现代浏览器都完整的支持  ECMAScript 5.1,旧版本的浏览器至少支持 ECMAScript 3 标准。2015年6月17日,ECMA国际组织发布了 ECMAScript 的第六版,该版本正式名称为 ECMAScript 2015,但通常被称为 ECMAScript 6 或者 ES6。自此,ECMAScript 每年发布一次新标准。本文档目前覆盖了最新 ECMAScript 的草案,也就是 ECMAScript2020

+ +

不要将 JavaScript 与 Java编程语言 混淆。虽然“Java”和“JavaScript”都是 Oracle 公司在美国和其他国家注册(或未注册)的商标,但是这两门语言在语法、语义与用途方面有很大不同。

+ +
+
+

教程

+ +

通过使用指南和教程来学习如何用JavaScript语言编程。

+ +

对于完全初学者

+ +

如果你想学习 JavaScript,但苦于没有过 JavaScript 或者其他语言的编程经验,你可以投入到我们的 JavaScript 主题学习区。那里有完整的学习资源:

+ +
+
JavaScript 第一步
+
回答一些基本问题,比如“JavaScript 是什么?”、“它是怎么样的?”、“它可以用来做什么?”;同时还讨论如变量、字符串、数值和数组等 JavaScript 的核心特性。
+
JavaScript 基本结构
+
继介绍了 JavaScript 基本的核心特性后,我们需要关注常见的代码块类型,如条件语句,循环,函数和事件。
+
介绍JavaScript 对象
+
如果你想进一步使用该语言撰写更有效率的代码,理解 JavaScript 面向对象的精髓是很重要的,因此我们提供了该模块来帮助你理解它。
+
+ +

JavaScript 指南

+ +
+
JavaScript 指南
+
一份更详尽的 JavaScript 指南,适用于有过 JavaScript 或其他语言编程经验的读者。
+
+ +

中级内容

+ +
+
客户端 Web API
+
当你正在给网页或者网页 APP 编写客户端 JavaScript 时, 你离不开使用这些 API — 这些用来操作浏览器各个不同方面和网页所在的操作系统,甚至是来自于其他网页和服务器的数据的接口。在这个模块,我们来探究这些 API 是什么,以及怎么在你的日常开发工作中使用一些最常用的 API。
+
+ +
+
重新介绍 JavaScript(JS 教程)
+
给那些有 JavaScript 基础的朋友们的 JavaScript概述。
+
+ +
+
JavaScript 数据结构
+
JavaScript 数据结构的概述。
+
如何使用比较操作符
+
JavaScript 提供了三种比较操作符,包括严格比较操作符 === 和非严格的比较操作符 ==,以及 {{jsxref("Global_Objects/Object/is", "Object.is()")}} 方法。
+
闭包
+
闭包是一个函数与其本身所被定义的词法环境的结合。
+
+ +

高级内容

+ +
+
继承和原型链
+
基于原型继承被外界广泛地误解与低估,这一版块对基于原型的继承作出详细解释。
+
严格模式
+
严格模式规定不能使用未定义的变量。严格模式是对 ECMAScript 5 的严格限制,以求得更高效的性能和更便利的调试。
+
JavaScript 类型数组
+
为使 JavaScript 处理原始二进制数据而提供的类型数组。
+
内存管理
+
JavaScript 中的内存生命周期和垃圾回收机制。
+
并发模型以及事件循环
+
JavaScript 具有基于“事件循环”的并发模型。
+
+
+ +
+

参考

+ +

浏览完整的 JavaScript 参考文档。

+ +
+
标准对象
+
标准的内置对象例如 {{jsxref("Array")}}, {{jsxref("Boolean")}}, {{jsxref("Date")}}, {{jsxref("Error")}}, {{jsxref("Function")}}, {{jsxref("JSON")}}, {{jsxref("Math")}}, {{jsxref("Number")}}, {{jsxref("Object")}}, {{jsxref("RegExp")}}, {{jsxref("String")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, {{jsxref("WeakMap")}} , {{jsxref("WeakSet")}} 以及其他对象
+
表达式和运算符
+
运算符的作用:{{jsxref("Operators/instanceof", "instanceof")}}, {{jsxref("Operators/typeof", "typeof")}}, {{jsxref("Operators/new", "new")}}, {{jsxref("Operators/this", "this")}},运算符优先级,以及其他运算符。
+
语句和声明
+
了解 {{jsxref("Statements/do...while", "do-while")}}, {{jsxref("Statements/for...in", "for-in")}}, {{jsxref("Statements/for...of", "for-of")}}, {{jsxref("Statements/try...catch", "try-catch")}}, {{jsxref("Statements/let", "let")}}, {{jsxref("Statements/var", "var")}}, {{jsxref("Statements/const", "const")}}, {{jsxref("Statements/if...else", "if-else")}}, {{jsxref("Statements/switch", "switch")}} 以及其他语句和关键字的作用。
+
函数
+
学习如何使用 JavaScript 函数来开发你的应用。
+
+ +

工具和资源

+ +

用于编写和调试 JavaScript 代码的实用工具。

+ +
+
Firefox 开发工具
+
包括 ScratchpadWeb ConsoleJavaScript ProfilerDebugger 等等
+
JavaScript Shells
+
允许您快速测试 JavaScript 代码片段。
+
TogetherJS
+
+

添加 TogetherJS 到您的网站,让用户实时互助,协作更简单。

+
+
Stack Overflow
+
你可以在 StackOverflow 查看或者发布带有 JavaScript 标签的问题。
+
JavaScript版本和发行记录
+
浏览 JavaScript 的历史版本特性和实现情况.
+
JSFiddle
+
编辑 JavaScript、CSS 和 HTML 并获得实时结果。使用外置资源,并和你的团队在线合作。
+
Plunker
+
Plunker 是一个在线社区,用于创建,协作和共享您的 Web 开发创意。编辑您的 JavaScript、CSS 和 HTML 文件并获取实时结果和文件结构。
+
JSBin
+
+

JS Bin 是一种开源的协作式的web 开发调试工具。

+
+
+
+
diff --git a/files/zh-cn/web/javascript/inheritance_and_the_prototype_chain/index.html b/files/zh-cn/web/javascript/inheritance_and_the_prototype_chain/index.html new file mode 100644 index 0000000000..c0dbb2c720 --- /dev/null +++ b/files/zh-cn/web/javascript/inheritance_and_the_prototype_chain/index.html @@ -0,0 +1,597 @@ +--- +title: 继承与原型链 +slug: Web/JavaScript/Inheritance_and_the_prototype_chain +tags: + - Advanced + - Guide + - Inheritance + - JavaScript + - OOP + - 指南 + - 继承 + - 进阶 + - 面向对象 + - 面向对象编程 + - 高级 +translation_of: Web/JavaScript/Inheritance_and_the_prototype_chain +--- +
{{jsSidebar("Advanced")}}
+ +

对于使用过基于类的语言 (如 Java 或 C++) 的开发人员来说,JavaScript 有点令人困惑,因为它是动态的,并且本身不提供一个 class 实现。(在 ES2015/ES6 中引入了 class 关键字,但那只是语法糖,JavaScript 仍然是基于原型的)。

+ +

当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象( object )都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( __proto__ ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

+ +

几乎所有 JavaScript 中的对象都是位于原型链顶端的 {{jsxref("Object")}} 的实例。

+ +

尽管这种原型继承通常被认为是 JavaScript 的弱点之一,但是原型继承模型本身实际上比经典模型更强大。例如,在原型模型的基础上构建经典模型相当简单。

+ +

基于原型链的继承

+ +

继承属性

+ +

JavaScript 对象是动态的属性“包”(指其自己的属性)。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

+ +
+

遵循ECMAScript标准,someObject.[[Prototype]] 符号是用于指向 someObject 的原型。从 ECMAScript 6 开始,[[Prototype]] 可以通过 {{jsxref("Object.getPrototypeOf()")}} 和 {{jsxref("Object.setPrototypeOf()")}} 访问器来访问。这个等同于 JavaScript 的非标准但许多浏览器实现的属性 __proto__

+ +

但它不应该与构造函数 funcprototype 属性相混淆。被构造函数创建的实例对象的 [[Prototype]] 指向 funcprototype 属性。Object.prototype 属性表示 {{jsxref("Object")}} 的原型对象。

+
+ +

这里演示当尝试访问属性时会发生什么:

+ +
// 让我们从一个函数里创建一个对象o,它自身拥有属性a和b的:
+let f = function () {
+   this.a = 1;
+   this.b = 2;
+}
+/* 这么写也一样
+function f() {
+  this.a = 1;
+  this.b = 2;
+}
+*/
+let o = new f(); // {a: 1, b: 2}
+
+// 在f函数的原型上定义属性
+f.prototype.b = 3;
+f.prototype.c = 4;
+
+// 不要在 f 函数的原型上直接定义 f.prototype = {b:3,c:4};这样会直接打破原型链
+// o.[[Prototype]] 有属性 b 和 c
+//  (其实就是 o.__proto__ 或者 o.constructor.prototype)
+// o.[[Prototype]].[[Prototype]] 是 Object.prototype.
+// 最后o.[[Prototype]].[[Prototype]].[[Prototype]]是null
+// 这就是原型链的末尾,即 null,
+// 根据定义,null 就是没有 [[Prototype]]。
+
+// 综上,整个原型链如下:
+
+// {a:1, b:2} ---> {b:3, c:4} ---> Object.prototype---> null
+
+console.log(o.a); // 1
+// a是o的自身属性吗?是的,该属性的值为 1
+
+console.log(o.b); // 2
+// b是o的自身属性吗?是的,该属性的值为 2
+// 原型上也有一个'b'属性,但是它不会被访问到。
+// 这种情况被称为"属性遮蔽 (property shadowing)"
+
+console.log(o.c); // 4
+// c是o的自身属性吗?不是,那看看它的原型上有没有
+// c是o.[[Prototype]]的属性吗?是的,该属性的值为 4
+
+console.log(o.d); // undefined
+// d 是 o 的自身属性吗?不是,那看看它的原型上有没有
+// d 是 o.[[Prototype]] 的属性吗?不是,那看看它的原型上有没有
+// o.[[Prototype]].[[Prototype]] 为 null,停止搜索
+// 找不到 d 属性,返回 undefined
+ +

代码来源链接:https://repl.it/@khaled_hossain_code/prototype

+ +

给对象设置属性会创建自有属性。获取和设置属性的唯一限制是内置 getter 或 setter 的属性。

+ +

继承方法

+ +

JavaScript 并没有其他基于类的语言所定义的“方法”。在 JavaScript 里,任何函数都可以添加到对象上作为对象的属性。函数的继承与其他的属性继承没有差别,包括上面的“属性遮蔽”(这种情况相当于其他语言的方法重写)。

+ +

当继承的函数被调用时,this 指向的是当前继承的对象,而不是继承的函数所在的原型对象。

+ +
var o = {
+  a: 2,
+  m: function(){
+    return this.a + 1;
+  }
+};
+
+console.log(o.m()); // 3
+// 当调用 o.m 时,'this' 指向了 o.
+
+var p = Object.create(o);
+// p是一个继承自 o 的对象
+
+p.a = 4; // 创建 p 的自身属性 'a'
+console.log(p.m()); // 5
+// 调用 p.m 时,'this' 指向了 p
+// 又因为 p 继承了 o 的 m 函数
+// 所以,此时的 'this.a' 即 p.a,就是 p 的自身属性 'a' 
+ +

在 JavaScript 中使用原型

+ +

接下去,来仔细分析一下这些应用场景下, JavaScript 在背后做了哪些事情。

+ +

正如之前提到的,在 JavaScript 中,函数(function)是允许拥有属性的。所有的函数会有一个特别的属性 —— prototype 。请注意,以下的代码是独立的(出于严谨,假定页面没有其他的JavaScript代码)。为了最佳的学习体验,我们强烈建议阁下打开浏览器的控制台(在Chrome和火狐浏览器中,按Ctrl+Shift+I即可),进入“console”选项卡,然后把如下的JavaScript代码复制粘贴到窗口中,最后通过按下回车键运行代码。

+ +
function doSomething(){}
+console.log( doSomething.prototype );
+// 和声明函数的方式无关,
+// JavaScript 中的函数永远有一个默认原型属性。
+var doSomething = function(){};
+console.log( doSomething.prototype );
+ +

在控制台显示的JavaScript代码块中,我们可以看到doSomething函数的一个默认属性prototype。而这段代码运行之后,控制台应该显示类似如下的结果:

+ +
{
+    constructor: ƒ doSomething(),
+    __proto__: {
+        constructor: ƒ Object(),
+        hasOwnProperty: ƒ hasOwnProperty(),
+        isPrototypeOf: ƒ isPrototypeOf(),
+        propertyIsEnumerable: ƒ propertyIsEnumerable(),
+        toLocaleString: ƒ toLocaleString(),
+        toString: ƒ toString(),
+        valueOf: ƒ valueOf()
+    }
+}
+ +

我们可以给doSomething函数的原型对象添加新属性,如下:

+ +
function doSomething(){}
+doSomething.prototype.foo = "bar";
+console.log( doSomething.prototype );
+ +

可以看到运行后的结果如下:

+ +
{
+    foo: "bar",
+    constructor: ƒ doSomething(),
+    __proto__: {
+        constructor: ƒ Object(),
+        hasOwnProperty: ƒ hasOwnProperty(),
+        isPrototypeOf: ƒ isPrototypeOf(),
+        propertyIsEnumerable: ƒ propertyIsEnumerable(),
+        toLocaleString: ƒ toLocaleString(),
+        toString: ƒ toString(),
+        valueOf: ƒ valueOf()
+    }
+}
+ +

现在我们可以通过new操作符来创建基于这个原型对象的doSomething实例。使用new操作符,只需在调用doSomething函数语句之前添加new。这样,便可以获得这个函数的一个实例对象。一些属性就可以添加到该原型对象中。

+ +

请尝试运行以下代码:

+ +
function doSomething(){}
+doSomething.prototype.foo = "bar"; // add a property onto the prototype
+var doSomeInstancing = new doSomething();
+doSomeInstancing.prop = "some value"; // add a property onto the object
+console.log( doSomeInstancing );
+ +

运行的结果类似于以下的语句。

+ +
{
+    prop: "some value",
+    __proto__: {
+        foo: "bar",
+        constructor: ƒ doSomething(),
+        __proto__: {
+            constructor: ƒ Object(),
+            hasOwnProperty: ƒ hasOwnProperty(),
+            isPrototypeOf: ƒ isPrototypeOf(),
+            propertyIsEnumerable: ƒ propertyIsEnumerable(),
+            toLocaleString: ƒ toLocaleString(),
+            toString: ƒ toString(),
+            valueOf: ƒ valueOf()
+        }
+    }
+}
+ +

如上所示, doSomeInstancing 中的__proto__是 doSomething.prototype. 但这是做什么的呢?当你访问doSomeInstancing 中的一个属性,浏览器首先会查看doSomeInstancing 中是否存在这个属性。

+ +

如果 doSomeInstancing 不包含属性信息, 那么浏览器会在 doSomeInstancing 的 __proto__ 中进行查找(同 doSomething.prototype). 如属性在 doSomeInstancing 的 __proto__ 中查找到,则使用 doSomeInstancing 中 __proto__ 的属性。

+ +

否则,如果 doSomeInstancing 中 __proto__ 不具有该属性,则检查doSomeInstancing 的 __proto__ 的  __proto__ 是否具有该属性。默认情况下,任何函数的原型属性 __proto__ 都是 window.Object.prototype. 因此, 通过doSomeInstancing 的 __proto__ 的  __proto__  ( 同 doSomething.prototype 的 __proto__ (同  Object.prototype)) 来查找要搜索的属性。

+ +

如果属性不存在 doSomeInstancing 的 __proto__ 的  __proto__ 中, 那么就会在doSomeInstancing 的 __proto__ 的  __proto__ 的  __proto__ 中查找。然而, 这里存在个问题:doSomeInstancing 的 __proto__ 的  __proto__ 的  __proto__ 其实不存在。因此,只有这样,在 __proto__ 的整个原型链被查看之后,这里没有更多的 __proto__ , 浏览器断言该属性不存在,并给出属性值为 undefined 的结论。

+ +

让我们在控制台窗口中输入更多的代码,如下:

+ +
function doSomething(){}
+doSomething.prototype.foo = "bar";
+var doSomeInstancing = new doSomething();
+doSomeInstancing.prop = "some value";
+console.log("doSomeInstancing.prop:      " + doSomeInstancing.prop);
+console.log("doSomeInstancing.foo:       " + doSomeInstancing.foo);
+console.log("doSomething.prop:           " + doSomething.prop);
+console.log("doSomething.foo:            " + doSomething.foo);
+console.log("doSomething.prototype.prop: " + doSomething.prototype.prop);
+console.log("doSomething.prototype.foo:  " + doSomething.prototype.foo);
+ +

结果如下:

+ +
doSomeInstancing.prop:      some value
+doSomeInstancing.foo:       bar
+doSomething.prop:           undefined
+doSomething.foo:            undefined
+doSomething.prototype.prop: undefined
+doSomething.prototype.foo:  bar
+ +

使用不同的方法来创建对象和生成原型链

+ +

使用语法结构创建的对象

+ +
var o = {a: 1};
+
+// o 这个对象继承了 Object.prototype 上面的所有属性
+// o 自身没有名为 hasOwnProperty 的属性
+// hasOwnProperty 是 Object.prototype 的属性
+// 因此 o 继承了 Object.prototype 的 hasOwnProperty
+// Object.prototype 的原型为 null
+// 原型链如下:
+// o ---> Object.prototype ---> null
+
+var a = ["yo", "whadup", "?"];
+
+// 数组都继承于 Array.prototype
+// (Array.prototype 中包含 indexOf, forEach 等方法)
+// 原型链如下:
+// a ---> Array.prototype ---> Object.prototype ---> null
+
+function f(){
+  return 2;
+}
+
+// 函数都继承于 Function.prototype
+// (Function.prototype 中包含 call, bind等方法)
+// 原型链如下:
+// f ---> Function.prototype ---> Object.prototype ---> null
+ +

使用构造器创建的对象

+ +

在 JavaScript 中,构造器其实就是一个普通的函数。当使用 new 操作符 来作用这个函数时,它就可以被称为构造方法(构造函数)。

+ +
function Graph() {
+  this.vertices = [];
+  this.edges = [];
+}
+
+Graph.prototype = {
+  addVertex: function(v){
+    this.vertices.push(v);
+  }
+};
+
+var g = new Graph();
+// g 是生成的对象,他的自身属性有 'vertices' 和 'edges'。
+// 在 g 被实例化时,g.[[Prototype]] 指向了 Graph.prototype。
+ +

使用 Object.create 创建的对象

+ +

ECMAScript 5 中引入了一个新方法:{{jsxref("Object.create()")}}。可以调用这个方法来创建一个新对象。新对象的原型就是调用 create 方法时传入的第一个参数:

+ +
var a = {a: 1};
+// a ---> Object.prototype ---> null
+
+var b = Object.create(a);
+// b ---> a ---> Object.prototype ---> null
+console.log(b.a); // 1 (继承而来)
+
+var c = Object.create(b);
+// c ---> b ---> a ---> Object.prototype ---> null
+
+var d = Object.create(null);
+// d ---> null
+console.log(d.hasOwnProperty); // undefined, 因为d没有继承Object.prototype
+ +

使用 class 关键字创建的对象

+ +

ECMAScript6 引入了一套新的关键字用来实现 class。使用基于类语言的开发人员会对这些结构感到熟悉,但它们是不同的。JavaScript 仍然基于原型。这些新的关键字包括 {{jsxref("Statements/class", "class")}}, {{jsxref("Classes/constructor", "constructor")}},{{jsxref("Classes/static", "static")}},{{jsxref("Classes/extends", "extends")}} 和 {{jsxref("Operators/super", "super")}}。

+ +
"use strict";
+
+class Polygon {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+}
+
+class Square extends Polygon {
+  constructor(sideLength) {
+    super(sideLength, sideLength);
+  }
+  get area() {
+    return this.height * this.width;
+  }
+  set sideLength(newLength) {
+    this.height = newLength;
+    this.width = newLength;
+  }
+}
+
+var square = new Square(2);
+ +

性能

+ +

在原型链上查找属性比较耗时,对性能有副作用,这在性能要求苛刻的情况下很重要。另外,试图访问不存在的属性时会遍历整个原型链。

+ +

遍历对象的属性时,原型链上的每个可枚举属性都会被枚举出来。要检查对象是否具有自己定义的属性,而不是其原型链上的某个属性,则必须使用所有对象从 Object.prototype 继承的 hasOwnProperty 方法。下面给出一个具体的例子来说明它:

+ +
console.log(g.hasOwnProperty('vertices'));
+// true
+
+console.log(g.hasOwnProperty('nope'));
+// false
+
+console.log(g.hasOwnProperty('addVertex'));
+// false
+
+console.log(g.__proto__.hasOwnProperty('addVertex'));
+// true
+ +

hasOwnProperty 是 JavaScript 中唯一一个处理属性并且不会遍历原型链的方法。(译者注:原文如此。另一种这样的方法:Object.keys()

+ +

注意:检查属性是否为 undefined不能够检查其是否存在的。该属性可能已存在,但其值恰好被设置成了 undefined

+ +

错误实践:扩展原生对象的原型

+ +

经常使用的一个错误实践是扩展 Object.prototype 或其他内置原型。

+ +

这种技术被称为猴子补丁并且会破坏封装。尽管一些流行的框架(如 Prototype.js)在使用该技术,但仍然没有足够好的理由使用附加的非标准方法来混入内置原型。

+ +

扩展内置原型的唯一理由是支持 JavaScript 引擎的新特性,如 Array.forEach

+ +

总结:4 个用于拓展原型链的方法

+ +

下面列举四种用于拓展原型链的方法,以及他们的优势和缺陷。下列四个例子都创建了完全相同的 inst 对象(所以在控制台上的输出也是一致的),为了举例,唯一的区别是他们的创建方法不同。

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称例子优势缺陷
New-initialization +
+function foo(){}
+foo.prototype = {
+  foo_prop: "foo val"
+};
+function bar(){}
+var proto = new foo;
+proto.bar_prop = "bar val";
+bar.prototype = proto;
+var inst = new bar;
+console.log(inst.foo_prop);
+console.log(inst.bar_prop);
+
支持目前以及所有可想象到的浏览器(IE5.5都可以使用)。 这种方法非常快,非常符合标准,并且充分利用JIT优化。为使用此方法,必须对相关函数初始化。 在初始化过程中,构造函数可以存储每个对象必须生成的唯一信息。但是,这种唯一信息只生成一次,可能会带来潜在的问题。此外,构造函数的初始化,可能会将不需要的方法放在对象上。然而,如果你只在自己的代码中使用,你也清楚(或有通过注释等写明)各段代码在做什么,这些在大体上都不是问题(事实上,通常是有益处的)。
Object.create +
+function foo(){}
+foo.prototype = {
+  foo_prop: "foo val"
+};
+function bar(){}
+var proto = Object.create(
+  foo.prototype
+);
+proto.bar_prop = "bar val";
+bar.prototype = proto;
+var inst = new bar;
+console.log(inst.foo_prop);
+console.log(inst.bar_prop);
+
+ +
+function foo(){}
+foo.prototype = {
+  foo_prop: "foo val"
+};
+function bar(){}
+var proto = Object.create(
+  foo.prototype,
+  {
+    bar_prop: {
+      value: "bar val"
+    }
+  }
+);
+bar.prototype = proto;
+var inst = new bar;
+console.log(inst.foo_prop);
+console.log(inst.bar_prop)
+
支持当前所有非微软版本或者 IE9 以上版本的浏览器。允许一次性地直接设置 __proto__ 属性,以便浏览器能更好地优化对象。同时允许通过 Object.create(null) 来创建一个没有原型的对象。不支持 IE8 以下的版本。然而,随着微软不再对系统中运行的旧版本浏览器提供支持,这将不是在大多数应用中的主要问题。 另外,这个慢对象初始化在使用第二个参数的时候有可能成为一个性能黑洞,因为每个对象的描述符属性都有自己的描述对象。当以对象的格式处理成百上千的对象描述的时候,可能会造成严重的性能问题。
+

Object.setPrototypeOf

+
+
+function foo(){}
+foo.prototype = {
+  foo_prop: "foo val"
+};
+function bar(){}
+var proto = {
+  bar_prop: "bar val"
+};
+Object.setPrototypeOf(
+  proto, foo.prototype
+);
+bar.prototype = proto;
+var inst = new bar;
+console.log(inst.foo_prop);
+console.log(inst.bar_prop);
+
+ +
+function foo(){}
+foo.prototype = {
+  foo_prop: "foo val"
+};
+function bar(){}
+var proto;
+proto=Object.setPrototypeOf(
+  { bar_prop: "bar val" },
+  foo.prototype
+);
+bar.prototype = proto;
+var inst = new bar;
+console.log(inst.foo_prop);
+console.log(inst.bar_prop)
+
支持所有现代浏览器和微软IE9+浏览器。允许动态操作对象的原型,甚至能强制给通过 Object.create(null) 创建出来的没有原型的对象添加一个原型。这个方式表现并不好,应该被弃用。如果你在生产环境中使用这个方法,那么快速运行 Javascript 就是不可能的,因为许多浏览器优化了原型,尝试在调用实例之前猜测方法在内存中的位置,但是动态设置原型干扰了所有的优化,甚至可能使浏览器为了运行成功,使用完全未经优化的代码进行重编译。 不支持 IE8 及以下的浏览器版本。
__proto__ +
+function foo(){}
+foo.prototype = {
+  foo_prop: "foo val"
+};
+function bar(){}
+var proto = {
+  bar_prop: "bar val",
+  __proto__: foo.prototype
+};
+bar.prototype = proto;
+var inst = new bar;
+console.log(inst.foo_prop);
+console.log(inst.bar_prop);
+
+ +
+var inst = {
+  __proto__: {
+    bar_prop: "bar val",
+    __proto__: {
+      foo_prop: "foo val",
+      __proto__: Object.prototype
+    }
+  }
+};
+console.log(inst.foo_prop);
+console.log(inst.bar_prop)
+
支持所有现代非微软版本以及 IE11 以上版本的浏览器。将 __proto__ 设置为非对象的值会静默失败,并不会抛出错误。应该完全将其抛弃因为这个行为完全不具备性能可言。 如果你在生产环境中使用这个方法,那么快速运行 Javascript 就是不可能的,因为许多浏览器优化了原型,尝试在调用实例之前猜测方法在内存中的位置,但是动态设置原型干扰了所有的优化,甚至可能使浏览器为了运行成功,使用完全未经优化的代码进行重编译。不支持 IE10 及以下的浏览器版本。
+
+ +

prototypeObject.getPrototypeOf

+ +

对于从 Java 或 C++ 转过来的开发人员来说,JavaScript 会有点让人困惑,因为它完全是动态的,都是运行时,而且不存在类(class)。所有的都是实例(对象)。即使我们模拟出的 “类”,也只是一个函数对象。

+ +

你可能已经注意到我们的 function A 有一个叫做 prototype 的特殊属性。该特殊属性可与 JavaScript 的 new 操作符一起使用。对原型对象的引用被复制到新实例的内部 [[Prototype]] 属性。例如,当执行 var a1 = new A(); 时,JavaScript(在内存中创建对象之后,和在运行函数 A()this 指向对象之前)设置 a1.[[Prototype]] = A.prototype;。然后当您访问实例的属性时,JavaScript 首先会检查它们是否直接存在于该对象上,如果不存在,则会 [[Prototype]] 中查找。这意味着你在 prototype 中定义的所有内容都可以由所有实例有效地共享,你甚至可以稍后更改部分 prototype,并在所有现有实例中显示更改(如果有必要的话)。

+ +

像上面的例子中,如果你执行 var a1 = new A(); var a2 = new A(); 那么 a1.doSomething 事实上会指向 Object.getPrototypeOf(a1).doSomething,它就是你在 A.prototype.doSomething 中定义的内容。也就是说:Object.getPrototypeOf(a1).doSomething == Object.getPrototypeOf(a2).doSomething == A.prototype.doSomething(补充:实际上,执行 a1.doSomething() 相当于执行 Object.getPrototypeOf(a1).doSomething.call(a1)==A.prototype.doSomething.call(a1)

+ +

简而言之, prototype 是用于类的,而 Object.getPrototypeOf() 是用于实例的(instances),两者功能一致。

+ +

[[Prototype]] 看起来就像递归引用, 如 a1.doSomethingObject.getPrototypeOf(a1).doSomethingObject.getPrototypeOf(Object.getPrototypeOf(a1)).doSomething 等等等, 直到它被找到或 Object.getPrototypeOf 返回 null

+ +

因此,当你执行:

+ +
var o = new Foo();
+ +

JavaScript 实际上执行的是:

+ +
var o = new Object();
+o.__proto__ = Foo.prototype;
+Foo.call(o);
+ +

(或者类似上面这样的),然后,当你执行:

+ +
o.someProp;
+ +

它检查 o 是否具有 someProp 属性。如果没有,它会查找 Object.getPrototypeOf(o).someProp,如果仍旧没有,它会继续查找 Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp

+ +

结论

+ +

在使用原型继承编写复杂代码之前,理解原型继承模型是至关重要的。此外,请注意代码中原型链的长度,并在必要时将其分解,以避免可能的性能问题。此外,原生原型不应该被扩展,除非它是为了与新的 JavaScript 特性兼容。

+ +
+

译者注:在英文原版中,以下内容已被移除。保留仅作参考。

+
+ +

示例

+ +

B 继承自 A

+ +
function A(a){
+  this.varA = a;
+}
+
+// 以上函数 A 的定义中,既然 A.prototype.varA 总是会被 this.varA 遮蔽,
+// 那么将 varA 加入到原型(prototype)中的目的是什么?
+A.prototype = {
+  varA : null,
+/*
+既然它没有任何作用,干嘛不将 varA 从原型(prototype)去掉 ?
+也许作为一种在隐藏类中优化分配空间的考虑 ?
+https://developers.google.com/speed/articles/optimizing-javascript
+如果varA并不是在每个实例中都被初始化,那这样做将是有效果的。
+*/
+  doSomething : function(){
+    // ...
+  }
+}
+
+function B(a, b){
+  A.call(this, a);
+  this.varB = b;
+}
+B.prototype = Object.create(A.prototype, {
+  varB : {
+    value: null,
+    enumerable: true,
+    configurable: true,
+    writable: true
+  },
+  doSomething : {
+    value: function(){ // override
+      A.prototype.doSomething.apply(this, arguments);
+      // call super
+      // ...
+    },
+    enumerable: true,
+    configurable: true,
+    writable: true
+  }
+});
+B.prototype.constructor = B;
+
+var b = new B();
+b.doSomething();
+ +

最重要的部分是:

+ + diff --git a/files/zh-cn/web/javascript/introduction_to_object-oriented_javascript/index.html b/files/zh-cn/web/javascript/introduction_to_object-oriented_javascript/index.html new file mode 100644 index 0000000000..affda5b740 --- /dev/null +++ b/files/zh-cn/web/javascript/introduction_to_object-oriented_javascript/index.html @@ -0,0 +1,361 @@ +--- +title: JavaScript面向对象简介 +slug: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript +tags: + - JavaScript + - OOP + - 命名空间 + - 对象 + - 封装 + - 成员 + - 构造函数 + - 继承 + - 面向对象 +translation_of: Learn/JavaScript/Objects +--- +
{{jsSidebar("Introductory")}}
+ +
 
+ +

JavaScript 的核心是支持面向对象的,同时它也提供了强大灵活的 OOP 语言能力。本文从对面向对象编程的介绍开始,带您探索 JavaScript 的对象模型,最后描述 JavaScript 当中面向对象编程的一些概念。

+ +

JavaScript回顾

+ +

如果您对 JavaScript 的概念(如变量、类型、方法和作用域等)缺乏自信,您可以在重新介绍 JavaScript 这篇文章里学习这些概念。您也可以查阅这篇 JavaScript 1.5 核心指南

+ +

面向对象编程

+ +

面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式。它使用先前建立的范例,包括模块化,多态和封装几种技术。今天,许多流行的编程语言(如Java,JavaScript,C#,C+ +,Python,PHP,Ruby和Objective-C)都支持面向对象编程(OOP)。

+ +

相对于「一个程序只是一些函数的集合,或简单的计算机指令列表。」的传统软件设计观念而言,面向对象编程可以看作是使用一系列对象相互协作的软件设计。 在 OOP 中,每个对象能够接收消息,处理数据和发送消息给其他对象。每个对象都可以被看作是一个拥有清晰角色或责任的独立小机器。

+ +

面向对象程序设计的目的是在编程中促进更好的灵活性和可维护性,在大型软件工程中广为流行。凭借其对模块化的重视,面向对象的代码开发更简单,更容易理解,相比非模块化编程方法 1, 它能更直接地分析, 编码和理解复杂的情况和过程。

+ +

术语

+ +
+
Namespace 命名空间
+
允许开发人员在一个独特,应用相关的名字的名称下捆绑所有功能的容器。
+
Class 类
+
定义对象的特征。它是对象的属性和方法的模板定义。
+
Object 对象
+
类的一个实例。
+
Property 属性
+
对象的特征,比如颜色。
+
Method 方法
+
对象的能力,比如行走。
+
Constructor 构造函数
+
对象初始化的瞬间,被调用的方法。通常它的名字与包含它的类一致。
+
Inheritance 继承
+
一个类可以继承另一个类的特征。
+
Encapsulation 封装
+
一种把数据和相关的方法绑定在一起使用的方法。
+
Abstraction 抽象
+
结合复杂的继承,方法,属性的对象能够模拟现实的模型。
+
Polymorphism 多态
+
多意为「许多」,态意为「形态」。不同类可以定义相同的方法或属性。
+
+ +

更多关于面向对象编程的描述,请参照维基百科的 面向对象编程 。

+ +

原型编程

+ +

基于原型的编程不是面向对象编程中体现的风格,且行为重用(在基于类的语言中也称为继承)是通过装饰它作为原型的现有对象的过程实现的。这种模式也被称为弱类化,原型化,或基于实例的编程。

+ +

原始的(也是最典型的)基于原型语言的例子是由大卫·安格尔和兰德尔·史密斯开发的。然而,弱类化的编程风格近来变得越来越流行,并已被诸如JavaScript,Cecil,NewtonScript,IO,MOO,REBOL,Kevo,Squeak(使用框架操纵Morphic组件),和其他几种编程语言采用。1

+ +

JavaScript面向对象编程

+ +

命名空间

+ +

命名空间是一个容器,它允许开发人员在一个独特的,特定于应用程序的名称下捆绑所有的功能。 在JavaScript中,命名空间只是另一个包含方法,属性,对象的对象。

+ +
+

注意:需要认识到重要的一点是:与其他面向对象编程语言不同的是,Javascript中的普通对象和命名空间在语言层面上没有区别。这点可能会让JavaScript初学者感到迷惑。

+
+ +

创造的JavaScript命名空间背后的想法很简单:一个全局对象被创建,所有的变量,方法和功能成为该对象的属性。使用命名空间也最大程度地减少应用程序的名称冲突的可能性。

+ +

我们来创建一个全局变量叫做 MYAPP

+ +
// 全局命名空间
+var MYAPP = MYAPP || {};
+ +

在上面的代码示例中,我们首先检查MYAPP是否已经被定义(是否在同一文件中或在另一文件)。如果是的话,那么使用现有的MYAPP全局对象,否则,创建一个名为MYAPP的空对象用来封装方法,函数,变量和对象。

+ +

我们也可以创建子命名空间:

+ +
// 子命名空间
+MYAPP.event = {};
+ +

下面是用于创建命名空间和添加变量,函数和方法的代码写法:

+ +
// 给普通方法和属性创建一个叫做MYAPP.commonMethod的容器
+MYAPP.commonMethod = {
+  regExForName: "", // 定义名字的正则验证
+  regExForPhone: "", // 定义电话的正则验证
+  validateName: function(name){
+    // 对名字name做些操作,你可以通过使用“this.regExForname”
+    // 访问regExForName变量
+  },
+
+  validatePhoneNo: function(phoneNo){
+    // 对电话号码做操作
+  }
+}
+
+// 对象和方法一起申明
+MYAPP.event = {
+    addListener: function(el, type, fn) {
+    //  代码
+    },
+   removeListener: function(el, type, fn) {
+    // 代码
+   },
+   getEvent: function(e) {
+   // 代码
+   }
+
+   // 还可以添加其他的属性和方法
+}
+
+//使用addListener方法的写法:
+MYAPP.event.addListener("yourel", "type", callback);
+ +

标准内置对象

+ +

JavaScript有包括在其核心的几个对象,例如,Math,Object,Array和String对象。下面的例子演示了如何使用Math对象的random()方法来获得一个随机数。

+ +
console.log(Math.random());
+
+ +
注意:这里和接下来的例子都假设名为 console.log 的方法全局有定义。console.log 实际上不是 JavaScript 自带的。
+ +

查看 JavaScript 参考:全局对象 了解 JavaScript 内置对象的列表。

+ +

JavaScript 中的每个对象都是 Object 对象的实例且继承它所有的属性和方法。

+ +

自定义对象

+ +

+ +

JavaScript是一种基于原型的语言,它没类的声明语句,比如C+ +或Java中用的。这有时会对习惯使用有类申明语句语言的程序员产生困扰。相反,JavaScript可用方法作类。定义一个类跟定义一个函数一样简单。在下面的例子中,我们定义了一个新类Person。

+ +
function Person() { }
+// 或
+var Person = function(){ }
+
+ +

对象(类的实例)

+ +

我们使用 new obj 创建对象 obj 的新实例, 将结果(obj 类型赋值给一个变量方便稍后调用。

+ +

在下面的示例中,我们定义了一个名为Person的类,然后我们创建了两个Person的实例(person1 and person2).

+ +
function Person() { }
+var person1 = new Person();
+var person2 = new Person();
+
+ +
注意:有一种新增的创建未初始化实例的实例化方法,请参考 Object.create
+ +

构造器

+ +

在实例化时构造器被调用 (也就是对象实例被创建时)。构造器是对象中的一个方法。 在JavaScript中函数就可以作为构造器使用,因此不需要特别地定义一个构造器方法,每个声明的函数都可以在实例化后被调用执行。

+ +

构造器常用于给对象的属性赋值或者为调用函数做准备。 在本文的后面描述了类中方法既可以在定义时添加,也可以在使用前添加。

+ +

在下面的示例中, Person类实例化时构造器调用一个 alert函数。

+ +
function Person() {
+  alert('Person instantiated');
+}
+
+var person1 = new Person();
+var person2 = new Person();
+
+ +

属性 (对象属性)

+ +

属性就是 类中包含的变量;每一个对象实例有若干个属性. 为了正确的继承,属性应该被定义在类的原型属性 (函数)中。

+ +

可以使用 关键字 this调用类中的属性, this是对当前对象的引用。 从外部存取(读/写)其属性的语法是: InstanceName.Property; 这与C++,Java或者许多其他语言中的语法是一样的 (在类中语法 this.Property 常用于set和get属性值)

+ +

在下面的示例中,我们为定义Person类定义了一个属性 firstName 并在实例化时赋初值。

+ +
function Person(firstName) {
+  this.firstName = firstName;
+  alert('Person instantiated');
+}
+
+var person1 = new Person('Alice');
+var person2 = new Person('Bob');
+
+// Show the firstName properties of the objects
+alert('person1 is ' + person1.firstName); // alerts "person1 is Alice"
+alert('person2 is ' + person2.firstName); // alerts "person2 is Bob"
+
+ +

方法(对象属性)

+ +

方法与属性很相似, 不同的是:一个是函数,另一个可以被定义为函数。 调用方法很像存取一个属性,  不同的是add () 在方法名后面很可能带着参数. 为定义一个方法, 需要将一个函数赋值给类的 prototype 属性; 这个赋值给函数的名称就是用来给对象在外部调用它使用的。

+ +

在下面的示例中,我们给Person类定义了方法 sayHello(),并调用了它.

+ +
function Person(firstName) {
+  this.firstName = firstName;
+}
+
+Person.prototype.sayHello = function() {
+  alert("Hello, I'm " + this.firstName);
+};
+
+var person1 = new Person("Alice");
+var person2 = new Person("Bob");
+
+// call the Person sayHello method.
+person1.sayHello(); // alerts "Hello, I'm Alice"
+person2.sayHello(); // alerts "Hello, I'm Bob"
+
+ +

在JavaScript中方法通常是一个绑定到对象中的普通函数, 这意味着方法可以在其所在context之外被调用。 思考下面示例中的代码:

+ +
function Person(firstName) {
+  this.firstName = firstName;
+}
+
+Person.prototype.sayHello = function() {
+  alert("Hello, I'm " + this.firstName);
+};
+
+var person1 = new Person("Alice");
+var person2 = new Person("Bob");
+var helloFunction = person1.sayHello;
+
+person1.sayHello();                                 // alerts "Hello, I'm Alice"
+person2.sayHello();                                 // alerts "Hello, I'm Bob"
+helloFunction();                                    // alerts "Hello, I'm undefined" (or fails
+                                                    // with a TypeError in strict mode)
+console.log(helloFunction === person1.sayHello);          // logs true
+console.log(helloFunction === Person.prototype.sayHello); // logs true
+helloFunction.call(person1);                        // logs "Hello, I'm Alice"
+
+ +

如上例所示, 所有指向sayHello函数的引用 ,包括 person1, Person.prototype, 和 helloFunction 等, 均引用了相同的函数.

+ +

在调用函数的过程中,this的值取决于我们怎么样调用函数.  在通常情况下,我们通过一个表达式person1.sayHello()来调用函数:即从一个对象的属性中得到所调用的函数。此时this被设置为我们取得函数的对象(即person1)。这就是为什么person1.sayHello() 使用了姓名“Alice”而person2.sayHello()使用了姓名“bob”的原因。 

+ +

然而我们使用不同的调用方法时, this的值也就不同了。当从变量 helloFunction()中调用的时候, this就被设置成了全局对象 (在浏览器中即window)。由于该对象 (非常可能地) 没有firstName 属性, 我们得到的结果便是"Hello, I'm undefined". (这是松散模式下的结果, 在 严格模式中,结果将不同(此时会产生一个error)。 但是为了避免混淆,我们在这里不涉及细节) 。另外,我们可以像上例末尾那样,使用Function#call (或者Function#apply)显式的设置this的值。

+ +
更多有关信息请参考 Function#call and Function#apply
+ +

继承

+ +

创建一个或多个类的专门版本类方式称为继承(Javascript只支持单继承)。 创建的专门版本的类通常叫做子类,另外的类通常叫做父类。 在Javascript中,继承通过赋予子类一个父类的实例并专门化子类来实现。在现代浏览器中你可以使用 Object.create 实现继承.

+ +
+

JavaScript 并不检测子类的 prototype.constructor (见 Object.prototype), 所以我们必须手动申明它.

+
+ +

在下面的例子中, 我们定义了 Student类作为 Person类的子类. 之后我们重定义了sayHello() 方法并添加了 sayGoodBye() 方法.

+ +
// 定义Person构造器
+function Person(firstName) {
+  this.firstName = firstName;
+}
+
+// 在Person.prototype中加入方法
+Person.prototype.walk = function(){
+  alert("I am walking!");
+};
+Person.prototype.sayHello = function(){
+  alert("Hello, I'm " + this.firstName);
+};
+
+// 定义Student构造器
+function Student(firstName, subject) {
+  // 调用父类构造器, 确保(使用Function#call)"this" 在调用过程中设置正确
+  Person.call(this, firstName);
+
+  // 初始化Student类特有属性
+  this.subject = subject;
+};
+
+// 建立一个由Person.prototype继承而来的Student.prototype对象.
+// 注意: 常见的错误是使用 "new Person()"来建立Student.prototype.
+// 这样做的错误之处有很多, 最重要的一点是我们在实例化时
+// 不能赋予Person类任何的FirstName参数
+// 调用Person的正确位置如下,我们从Student中来调用它
+Student.prototype = Object.create(Person.prototype); // See note below
+
+// 设置"constructor" 属性指向Student
+Student.prototype.constructor = Student;
+
+// 更换"sayHello" 方法
+Student.prototype.sayHello = function(){
+  console.log("Hello, I'm " + this.firstName + ". I'm studying " + this.subject + ".");
+};
+
+// 加入"sayGoodBye" 方法
+Student.prototype.sayGoodBye = function(){
+  console.log("Goodbye!");
+};
+
+// 测试实例:
+var student1 = new Student("Janet", "Applied Physics");
+student1.sayHello();   // "Hello, I'm Janet. I'm studying Applied Physics."
+student1.walk();       // "I am walking!"
+student1.sayGoodBye(); // "Goodbye!"
+
+// Check that instanceof works correctly
+console.log(student1 instanceof Person);  // true
+console.log(student1 instanceof Student); // true
+
+ +

对于“Student.prototype = Object.create(Person.prototype);”这一行,在不支持 Object.create方法的老JavaScript引擎中,可以使用一个"polyfill"(又名"shim",查看文章链接),或者使用一个function来获得相同的返回值,就像下面:

+ +
function createObject(proto) {
+    function ctor() { }
+    ctor.prototype = proto;
+    return new ctor();
+}
+
+// Usage:
+Student.prototype = createObject(Person.prototype);
+
+ +
更多相关信息请参考 Object.create,连接中还有一个老JavaScript引擎的兼容方案(shim)。
+ +

封装

+ +

在上一个例子中,Student类虽然不需要知道Person类的walk()方法是如何实现的,但是仍然可以使用这个方法;Student类不需要明确地定义这个方法,除非我们想改变它。 这就叫做封装,对于所有继承自父类的方法,只需要在子类中定义那些你想改变的即可。

+ +

抽象

+ +

抽象是允许模拟工作问题中通用部分的一种机制。这可以通过继承(具体化)或组合来实现。
+ JavaScript通过继承实现具体化,通过让类的实例是其他对象的属性值来实现组合。

+ +

JavaScript Function 类继承自Object类(这是典型的具体化) 。Function.prototype的属性是一个Object实例(这是典型的组合)。

+ +
var foo = function(){};
+console.log( 'foo is a Function: ' + (foo instanceof Function) );                  // logs "foo is a Function: true"
+console.log( 'foo.prototype is an Object: ' + (foo.prototype instanceof Object) ); // logs "foo.prototype is an Object: true"
+ +

多态

+ +

就像所有定义在原型属性内部的方法和属性一样,不同的类可以定义具有相同名称的方法;方法是作用于所在的类中。并且这仅在两个类不是父子关系时成立(继承链中,一个类不是继承自其他类)。

+ +

注意

+ +

本文中所展示的面向对象编程技术不是唯一的实现方式,在JavaScript中面向对象的实现是非常灵活的。

+ +

同样的,文中展示的技术没有使用任何语言hacks,它们也没有模仿其他语言的对象理论实现。

+ +

JavaScript中还有其他一些更加先进的面向对象技术,但这些都超出了本文的介绍范围。

+ +

参考

+ +
    +
  1. 维基百科。「面向对象程序设计」,http://zh.wikipedia.org/wiki/面向对象程序设计​
  2. +
  3. 维基百科。“Encapsulation (object-oriented programming)
  4. +
diff --git a/files/zh-cn/web/javascript/introduction_to_using_xpath_in_javascript/index.html b/files/zh-cn/web/javascript/introduction_to_using_xpath_in_javascript/index.html new file mode 100644 index 0000000000..cc4b806fa6 --- /dev/null +++ b/files/zh-cn/web/javascript/introduction_to_using_xpath_in_javascript/index.html @@ -0,0 +1,436 @@ +--- +title: Introduction to using XPath in JavaScript +slug: Web/JavaScript/Introduction_to_using_XPath_in_JavaScript +tags: + - DOM + - Extensions + - Transforming_XML_with_XSLT + - Web Development + - XPath +translation_of: Web/XPath/Introduction_to_using_XPath_in_JavaScript +--- +

该篇文档描述了如何在扩展和网站内部通过JavaScript调用 XPath 接口。 Mozilla 实现了相当多的 DOM 3 XPath,意味着 Xpath 表达式已经可以在 HTML 和 XML 文档中使用。

+ +

使用 XPath 的主要接口是 document 对象的 evaluate 方法。

+ +

document.evaluate

+ +

此方法针对基于 XML 的文档(包括 HTML 文档)评估 XPath 表达式,并返回 XPathResult 对象,该对象可以是单个节点或一组节点。这个方法的现有文档位于 document.evaluate,但是对于我们现在的需求来说它相当稀疏;下面将给出更全面的研究。

+ +
var xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result );
+
+ +

参数

+ +

evaluate 函数共有五个参数:

+ + + +

返回值

+ +

返回 xpathResult,它是 resultType 参数中指定的类型的 XPathResult 对象。XPathResult 在这里定义。

+ +

实现默认的命名空间解析器

+ +

我们使用 document 对象的 createNSResolver 方法创建一个命名空间解析器。

+ +
var nsResolver = document.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement );
+
+ +

Or alternatively by using the <code>createNSResolver</code> method of a <code>XPathEvaluator</code> object. <pre> var xpEvaluator = new XPathEvaluator(); var nsResolver = xpEvaluator.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement ); </pre>

+ +

然后传递 document.evaluate,将 nsResolver 变量作为 namespaceResolver 参数。

+ +

注意:XPath 定义不带前缀的 QNames,以仅匹配 null 命名空间中的元素。XPath 没有办法选择应用于常规元素引用的默认命名空间(例如,p[@id='_myid'] 对应于 xmlns='http://www.w3.org/1999/xhtml')。要匹配非命名空间中的默认元素,您必须使用如 [namespace-uri()='http://www.w3.org/1999/xhtml' and name()='p' and @id='_id']这种方法适用于命名空间未知的动态 XPath),或者使用前缀名测试,并创建一个命名空间解析器将前缀映射到命名空间。如果你想采取后一种方法,阅读更多关于如何创建一个用户定义的命名空间解析器

+ +

注意

+ +

适应任何 DOM 节点以解析命名空间,以便可以相对于文档中出现的节点的上下文轻松地评估 XPath 表达式。此适配器的工作方式类似于 DOM 级别 3 方法 lookupNamespaceURI 在解析 namespaceuRI 时节点的层次结构中的可用的当前信息的节点。也正确解析了隐式 xml 前缀。

+ +

指定返回类型

+ +

document.evaluate 返回的变量 xpathResult 可以由单个节点(简单类型)或节点集合(节点集类型)组成。

+ +

简单类型

+ +

resultType 中的所需结果类型指定为:

+ + + +

我们通过分别访问 XPathResult 对象的以下属性来获取表达式的返回值。

+ + + +
示例
+ +

以下使用 XPath 表达式 count(//p) 来获取 HTML 文档中的 <p> 元素数:

+ +
var paragraphCount = document.evaluate( 'count(//p)', document, null, XPathResult.ANY_TYPE, null );
+
+alert( 'This document contains ' + paragraphCount.numberValue + ' paragraph elements' );
+
+ +

虽然 JavaScript 允许我们将数字转换为一个字符串进行显示,但 XPath 接口不会自动转换数字结果,如果 stringValue 属性被请求,所以下面的代码将工作:

+ +
var paragraphCount = document.evaluate('count(//p)', document, null, XPathResult.ANY_TYPE, null );
+
+alert( 'This document contains ' + paragraphCount.stringValue + ' paragraph elements' );
+
+ +

相反,它将返回一个带有 NS_DOM_TYPE_ERROR 的异常。

+ +

节点集类型

+ +

XPathResult 对象允许以 3 种主要不同类型返回节点集:

+ + + +
Iterators
+ +

resultType 参数中的指定结果类型为:

+ + + +

返回的 XPathResult 对象是一个匹配节点的节点集,它将作为迭代器,允许我们使用 XPathResultiterateNext() 方法访问包含的各个节点。

+ +

一旦迭代完成所有的匹配节点,iterateNext() 将返回 null

+ +

但请注意,如果在迭代过程中,文档发生突变(文档树被修改),将使迭代无效,并且 XPathResultinvalidIteratorState 属性设置为 true,抛出 NS_ERROR_DOM_INVALID_STATE_ERR 异常。

+ +
Iterator Example
+ +
var iterator = document.evaluate('//phoneNumber', documentNode, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );
+
+try {
+  var thisNode = iterator.iterateNext();
+
+  while (thisNode) {
+    alert( thisNode.textContent );
+    thisNode = iterator.iterateNext();
+  }
+}
+catch (e) {
+  dump( 'Error: Document tree modified during iteration ' + e );
+}
+
+ +
Snapshots
+ +

resultType 参数中的指定结果类型为:

+ + + +

返回的 XPathResult 对象是一个匹配节点的静态节点集,这允许我们通过 XPathResult 对象的 snapshotItem(itemNumber) 方法访问每个节点,其中 itemNumber 是要检索的节点的索引。包含的节点总数可以通过 snapshotLength 属性访问。

+ +

快照不随文档突变而改变,因此与迭代器不同,快照不会变得无效,但是它可能不对应于当前文档,例如节点可能已被移动,它可能包含不再存在的节点,或新节点可能已添加。

+ +
Snapshot Example
+ +
var nodesSnapshot = document.evaluate('//phoneNumber', documentNode, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
+
+for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ )
+{
+  dump( nodesSnapshot.snapshotItem(i).textContent );
+}
+
+ +
First Node
+ +

resultType 参数中的指定结果类型为:

+ + + +

返回的 XPathResult 对象只是匹配 XPath 表达式的第一个找到的节点。这可以通过 XPathResult 对象的 singleNodeValue 属性访问。如果节点集为空,这将为 null

+ +

请注意,对于无序子类型,返回的单个节点可能不是文档顺序中的第一个,但是对于有序子类型,保证以文档顺序获取第一个匹配的节点。

+ +
First Node Example
+ +
var firstPhoneNumber = document.evaluate('//phoneNumber', documentNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null );
+
+dump( 'The first phone number found is ' + firstPhoneNumber.singleNodeValue.textContent );
+
+ +

ANY_TYPE 常量

+ +

resultType 参数中的结果类型指定为 ANY_TYPE 时,返回的 XPathResult 对象将是由表达式求值自然产生的任何类型。

+ +

它可以是任何简单类型(NUMBER_TYPESTRING_TYPEBOOLEAN_TYPE ),如果返回的结果类型是节点集,那么它将是一个 UNORDERED_NODE_ITERATOR_TYPE

+ +

要在评估后确定类型,我们使用 XPathResult 对象的 resultType 属性。此属性的常量值在附录中定义。 None Yet =====Any_Type Example===== <pre> </pre>

+ +

示例

+ +

在 HTML 文档中

+ +

以下代码旨在放置在要针对其评估 XPath 表达式的 HTML 文档中内嵌或外链的任何 JavaScript 片段中。

+ +

要使用 XPath 提取 HTML 文档中的所有 <h2> 标题元素,xpathExpression 只是 //h2。其中,// 是递归下降运算符,在文档树中的任何位置将元素与 nodeName h2 相匹配。这个的完整代码是: link to introductory xpath doc

+ +
var headings = document.evaluate('//h2', document, null, XPathResult.ANY_TYPE, null );
+
+ +

请注意,由于 HTML 没有命名空间,因此我们为 namespaceResolver 参数传递了 null

+ +

因为希望在整个文档中搜索标题,所以我们使用 document 对象本身作为 contextNode

+ +

此表达式的结果是 XPathResult 对象。如果想知道返回的结果的类型,我们可以评估返回的对象的 resultType 属性。在这种情况下,这将评估为 4,即 UNORDERED_NODE_ITERATOR_TYPE。这是 XPath 表达式的结果是节点集时的默认返回类型。它一次提供对单个节点的访问,并且可能不以特定顺序返回节点。要访问返回的节点,我们使用返回对象的 iterateNext() 方法:

+ +
var thisHeading = headings.iterateNext();
+
+var alertText = 'Level 2 headings in this document are:\n'
+
+while (thisHeading) {
+  alertText += thisHeading.textContent + '\n';
+  thisHeading = headings.iterateNext();
+}
+
+ +

一旦迭代到一个节点,我们就可以访问该节点上的所有标准 DOM 接口。在遍历从表达式返回的所有 h2 元素之后,对 iterateNext() 的任何进一步调用都将返回 null 。

+ +

针对扩展中的 XML 文档进行评估

+ +

以下使用位于 chrome://yourextension/content/peopleDB.xml 的 XML 文档作为示例。

+ +
<?xml version="1.0"?>
+<people xmlns:xul = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" >
+  <person>
+  <name first="george" last="bush" />
+  <address street="1600 pennsylvania avenue" city="washington" country="usa"/>
+  <phoneNumber>202-456-1111</phoneNumber>
+  </person>
+  <person>
+  <name first="tony" last="blair" />
+  <address street="10 downing street" city="london" country="uk"/>
+  <phoneNumber>020 7925 0918</phoneNumber>
+  </person>
+</people>
+
+ +

为了使 XML 文档的内容在扩展中可用,我们创建一个 XMLHttpRequest 对象以同步加载文档,变量 xmlDoc 将包含该文档作为 XMLDocument 对象,我们可以使用 evaluate 方法。

+ +

JavaScript用于扩展 xul/js 文档。

+ +
var req = new XMLHttpRequest();
+
+req.open("GET", "chrome://yourextension/content/peopleDB.xml", false);
+req.send(null);
+
+var xmlDoc = req.responseXML;
+
+var nsResolver = xmlDoc.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement);
+
+var personIterator = xmlDoc.evaluate('//person', xmlDoc, nsResolver, XPathResult.ANY_TYPE, null );
+
+ +

注意

+ +

当未定义 XPathResult 对象时,可以使用 Components.interfaces.nsIDOMXPathResult.ANY_TYPE (CI.nsIDOMXPathResult) 在特权代码中检索常量。类似地,可以使用以下创建 XPathEvaluator:

+ +
Components.classes["@mozilla.org/dom/xpath-evaluator;1"].createInstance(Components.interfaces.nsIDOMXPathEvaluator)
+ +

附录

+ +

实现用户定义的命名空间解析器

+ +

这只是一个例子。此函数将需要从 xpathExpression 获取命名空间前缀,并返回与该前缀对应的 URI。例如,表达式:

+ +
'//xhtml:td/mathml:math'
+
+ +

将选择作为 (X)HTML 表数据单元元素的子项的所有 MathML 表达式。

+ +

为了将使用命名空间 URI http://www.w3.org/1998/Math/MathMLmathml: 前缀和使用 URI http://www.w3.org/1999/xhtmlxhtml: 关联,我们提供了一个函数:

+ +
function nsResolver(prefix) {
+  var ns = {
+    'xhtml' : 'http://www.w3.org/1999/xhtml',
+    'mathml': 'http://www.w3.org/1998/Math/MathML'
+  };
+  return ns[prefix] || null;
+}
+
+ +

我们对 document.evaluate 的调用将如下所示:

+ +
document.evaluate( '//xhtml:td/mathml:math', document, nsResolver, XPathResult.ANY_TYPE, null );
+
+ +

为 XML 文档实现默认命名空间

+ +

如前面实现默认命名空间解析器中所述,默认解析器不处理 XML 文档的默认命名空间。 例如使用本文档:

+ +
<?xml version="1.0" encoding="UTF-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+    <entry />
+    <entry />
+    <entry />
+</feed>
+
+ +

doc.evaluate('//entry', doc, nsResolver, XPathResult.ANY_TYPE, null) 将返回一个空集,其中 nsResolver 是 createNSResolver 返回的解析器。传递一个 null 解析器再好不过了。

+ +

一种可能的解决方法是创建一个自定义解析器,返回正确的默认命名空间(本例中为 Atom 命名空间)。请注意,您仍然必须在 XPath 表达式中使用一些命名空间前缀,以便解析器函数能够将其更改为所需的命名空间。例如:

+ +
function resolver() {
+    return 'http://www.w3.org/2005/Atom';
+}
+doc.evaluate('//myns:entry', doc, resolver, XPathResult.ANY_TYPE, null)
+
+ +

请注意,如果文档使用多个命名空间,则需要更复杂的解析器。

+ +

下一节将介绍一种可能更好的方法(并允许不提前知道命名空间)。

+ +

使用XPath函数引用具有默认命名空间的元素

+ +

另一种匹配非空命名空间中的默认的元素的方法(以及对于动态 XPath 表达式很有效,其中命名空间可能未知),涉及使用如 [namespace-uri()='http://www.w3.org/1999/xhtml' and name()='p' and @id='_myid']。这避免了 XPath 查询无法检测到定期标记的元素上的默认命名空间的问题。

+ +

获取特定的命名空间元素和属性,而不考虑前缀

+ +

如果希望在命名空间(像预期的那样)中提供灵活性,当发现命名空间元素或属性时不一定需要使用特定的前缀,必须使用特殊技术。

+ +

虽然可以修改上述部分中的方法来测试命名空间元素,而不管选择的前缀(使用 local-name() 结合 namespace-uri() 而不是 name()),但是会发生更具挑战性的情况,如果希望在谓词中获取具有特定命名空间属性的元素(假设在 XPath 1.0 中没有与实现无关的变量)。

+ +

例如,可能尝试(不正确地)使用 namespaced 属性获取元素,如下所示: var xpathlink = someElements[local-name(@*)="href" and namespace-uri(@*)='http://www.w3.org/1999/xlink'];

+ +

这可能会无意中抓取一些元素,如果它的一个属性存在,本地名称为 href,但它是一个不同的属性,有目标(XLink)命名空间(而不是 @href)。

+ +

为了使用 XLink @href 属性(而不仅限于命名空间解析器中的预定义前缀)精确地抓取元素,可以按如下方式获取它们:

+ +
var xpathEls = 'someElements[@*[local-name() = "href" and namespace-uri() = "http://www.w3.org/1999/xlink"]]'; // Grabs elements with any single attribute that has both the local name 'href' and the XLink namespace
+var thislevel = xml.evaluate(xpathEls, xml, null, XPathResult.ANY_TYPE, null);
+var thisitemEl = thislevel.iterateNext();
+
+ +

XPathResult 定义的常量

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
结果类型定义的常数描述
ANY_TYPE0包含任何类型的结果集,从表达式的评估中自然地产生。注意,如果结果是节点集,则 UNORDERED_NODE_ITERATOR_TYPE 始终是结果类型。
NUMBER_TYPE1包含单个数字的结果。这非常有用,例如,在 XPath 表达式中使用 count() 函数。
STRING_TYPE2包含单个字符串的结果。
BOOLEAN_TYPE3包含单个布尔值的结果。这非常有用,例如,在 XPath 表达式中使用 not() 函数。
UNORDERED_NODE_ITERATOR_TYPE4包含与表达式匹配的所有节点的结果节点集。节点可能不一定与它们在文档中出现的顺序相同。
ORDERED_NODE_ITERATOR_TYPE5包含与表达式匹配的所有节点的结果节点集。结果集中的节点与文档中显示的节点顺序相同。
UNORDERED_NODE_SNAPSHOT_TYPE6包含与表达式匹配的所有节点的快照的结果节点集。节点可能不一定与它们在文档中出现的顺序相同。
ORDERED_NODE_SNAPSHOT_TYPE7包含与表达式匹配的所有节点的快照的结果节点集。结果集中的节点与文档中显示的节点顺序相同。
ANY_UNORDERED_NODE_TYPE8包含与表达式匹配的任何单个节点的结果节点集。该节点不一定是文档中与表达式匹配的第一个节点。
FIRST_ORDERED_NODE_TYPE9包含文档中与表达式匹配的第一个节点的结果节点集。
+ +

参见

+ + + +
+

Original Document Information

+ + +
+ +

 

diff --git "a/files/zh-cn/web/javascript/javascript(\350\265\267\346\255\245)/index.html" "b/files/zh-cn/web/javascript/javascript(\350\265\267\346\255\245)/index.html" new file mode 100644 index 0000000000..b9cd157ec1 --- /dev/null +++ "b/files/zh-cn/web/javascript/javascript(\350\265\267\346\255\245)/index.html" @@ -0,0 +1,292 @@ +--- +title: javascript(起步) +slug: Web/JavaScript/javascript(起步) +tags: + - bug-840092 +--- +

JavaScript是什么?

+ +

作为一门计算机语言,JavaScript本身强大、复杂,且难于理解。但是,你可以用它来开发一系列的应用程序,它有巨大的潜力来改变当前的互联网现状。下面这个应用程序就是一个很好的例子:Google Maps

+ +

JavaScript(通称为ECMAScript)最大的优势在于,它基于浏览器,但是通过浏览器的支持可以在不同平台上生产出相同结果。 本文举出的例子是 Google Maps,它几乎可以无差别的运行在 Linux、Windows和Mac OS系统中。 伴随大量JavaScript类库的出现,你现在可以用它很轻易的实现文档导航、DOM元素选择、创建动画、处理事件和开发AJAX应用。同其他因各种利益目的而推动的技术不同,JavaScript是一种真正免费并且被广泛采用的跨平台编程语言。

+ +

你应该知道

+ +

JavaScript是一种非常容易入门的编程语言。你只需要一个文本编辑器和web浏览器就可以开始进行学习。 

+ +

在使用 JavaScript进行开发的过程中,可能还会涉及很多其他技术,这不在本文讨论的范围之内。 所以,不要期望在学习的第一天就能开发出一个类似 Google maps 这样的应用程序。

+ +

起步

+ +

JavaScript的起步非常简单。你不需要进行复杂的程序安装,不需要去了解如何使用shell、打包器或编译器。它是通过浏览器来展示的,你所需要做的全部事情就是把你的代码保存为文本文件,然后再浏览器中打开。就这么简单!

+ +

JavaScript非常适合作为入门级的编程语言。它直观形象,并且教会学生认识到这是一个在实际生活中非常有用的工具。 对比C、C++和 Java等语言会发现有很大不同,它们只对那些专业的软件开发者来说是有价值的。

+ +

浏览器兼容问题

+ +

不同浏览器在功能实现上有很多不同之处。Mozilla, Microsoft IE, Apple Safari 和 Opera 在行为上有很多差异。 我们计划在此记录这些差异 documenting these variations。你可以使用各种跨平台的JavaScript API接口来解决这些兼容性问题。这些API隐藏了浏览器之间的各种差异,提供了通用性的功能函数来方便调用。

+ +

如何运行示例

+ +

下面的例子都有相同的代码。要执行它们有多种方法,如果你有自己的个人站点,你还可以在站点上把这些例子保存为新的页面。

+ +

如果你没有自己的个人站点,你可以在电脑上把这些例子保存下来,并使用你自己的浏览器来执行它们。这就是JavaScript简单的地方,也是它适合做入门语言的原因。你不需要编译器或者开发环境,你只需要一个浏览器就可以开始起步了。

+ +

举例:捕获一个鼠标单击事件

+ +

事件处理 (事件类型、事件注册、冒泡等) 的细节是一个非常宽泛的话题,这个简单的例子并不能说明所有的问题。然而,如果我们不涉及JavaScript事件系统,我们就不能很好展示一个鼠标点击捕获的范例。你只需要记得例子里展示的只是JavaScrpt事件系统里非常表象的一些东西,如果你想要了解更多的内部细节,那你可以去查找更详细的相关资料。

+ +

鼠标事件只是浏览器同用户交互过程中所产生的事件系统里的一个子集。下面列举了一些用户在交互过程中产生的具体的鼠标事件:

+ + + +

捕获事件并注册处理函数最简单的办法就是使用HTML,你可以把事件当成元素属性来使用。例子:

+ +
  <span onclick="alert('Hello World!');">Click Here</span>
+ +

要执行的JavaScript代码既可以作为属性值写在行内位置,也可以写成函数并用<script>包裹后放到HTML页面中:

+ +
<script type="text/javascript">
+  function onclick_callback () {
+     alert ("Hello, World!");
+  }
+</script>
+<span onclick="onclick_callback();">Click Here</span>
+ +

另外,事件对象是可以被捕获和引用,开发者可以通过访问事件对象来获取更多信息,如捕获事件的对象、事件类型、哪个鼠标按键被点击等。我们还用上面的例子来说明:

+ +
<script type="text/javascript">
+  function onclick_callback(event) {
+    var eType = event.type;
+    /* the following is for compatability */
+    /* Moz populates the target property of the event object */
+    /* IE populates the srcElement property */
+    var eTarget = event.target || event.srcElement;
+
+    alert( "Captured Event (type=" + eType + ", target=" + eTarget );
+  }
+</script>
+<span onclick="onclick_callback(event);">Click Here</span>
+ +

对于事件的注册和接收还用注意一些的是,你可以给任何使用JavaScript生成的HTMLElement对象做相同的操作。下面的例子展示了一个这样的过程:生成span对象,添加到页面中的body,给span注册mouse-over、mouse-out、mouse-down和 mouse-up事件。

+ +
<script type="text/javascript">
+  function mouseevent_callback(event) {
+    /* The following is for compatability */
+    /* IE does NOT by default pass the event object */
+    /* obtain a ref to the event if one was not given */
+    if (!event) event = window.event;
+
+    /* obtain event type and target as earlier */
+    var eType = event.type;
+    var eTarget = event.target || event.srcElement;
+    alert(eType +' event on element with id: '+ eTarget.id);
+  }
+
+ function onload () {
+   /* obtain a ref to the 'body' element of the page */
+   var body = document.body;
+   /* create a span element to be clicked */
+   var span = document.createElement('span');
+   span.id = 'ExampleSpan';
+   span.appendChild(document.createTextNode ('Click Here!'));
+
+   /* register the span object to receive specific mouse events */
+   span.onmousedown = mouseevent_callback;
+   span.onmouseup = mouseevent_callback;
+   span.onmouseover = mouseevent_callback;
+   span.onmouseout = mouseevent_callback;
+
+   /* display the span on the page */
+   body.appendChild(span);
+}
+</script>
+ +

{{ draft() }}

+ +

举例:捕获一个键盘事件

+ +

同上面的例子类似,键盘事件捕获也依赖于JavaScript事件系统。当键盘上的键被使用的时候触发键盘事件。

+ +

下面的列表展示了一些具体的键盘事件,同鼠标事件相比是很少的:

+ + + +

在一个 keypress 事件中,键值的Unicode编码会存储到属性keyCode或者charCode 中,但是两者不会同时存在。按键会生成一个字母 (如 'a'),这时会把字母的编码存储到charCode 中,注意这里是区分大小写的( charCode 会判断shift键是否同时被按下)。其他情况下,编码会存储到 keyCode中。

+ +

捕获键盘事件最简单的方法仍然是在HTML中注册键盘事件的处理函数,在元素属性中处理相关事件。 举例:

+ +
  <input type="text" onkeypress="alert ('Hello World!');"></input>
+
+ +

同鼠标事件类似,你的 JavaScript代码既可以写到属性值内,也可以作为函数用<script包裹后写到HTML页面中:

+ +
<script type="text/javascript">
+  function onkeypress_callback () {
+    alert ("Hello, World!");
+  }
+</script>
+
+<input onkeypress="onkeypress_callback();"></input>
+
+ +

捕获事件和引用事件源(一个真实的键被按下时) 的方法同鼠标事件类似:

+ +
<script type="text/javascript">
+  function onkeypress_callback(evt) {
+      var eType = evt.type; // Will return "keypress" as the event type
+      var eCode = 'keyCode is ' + evt.keyCode;
+      var eChar = 'charCode is ' + evt.charCode;
+
+      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
+   }
+</script>
+<input onkeypress="onkeypress_callback(event);"></input>
+ +

要捕获页面上所有的键盘事件,可以在document上注册和绑定相关的处理函数:

+ +
<script type="text/javascript">
+  document.onkeypress = key_event;
+  document.onkeydown = key_event;
+  document.onkeyup = key_event;
+
+  function key_event(evt) {
+      var eType = evt.type;
+      var eCode = "ASCII code is " + evt.keyCode;
+      var eChar = 'charCode is ' + evt.charCode;
+
+      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
+   }
+</script>
+ +

下面是一个完整的键盘事件处理过程:

+ +
<!DOCTYPE html>
+<html>
+<head>
+  <script>
+    var metaChar = false;
+    var exampleKey = 16;
+    function keyEvent(event) {
+      var key = event.keyCode || event.which;
+      var keychar = String.fromCharCode(key);
+      if (key==exampleKey) { metaChar = true; }
+      if (key!=exampleKey) {
+         if (metaChar) {
+            alert("Combination of metaKey + " + keychar)
+            metaChar = false;
+         } else { alert("Key pressed " + key); }
+      }
+    }
+    function metaKeyUp (event) {
+      var key = event.keyCode || event.which;
+      if (key==exampleKey) { metaChar = false; }
+    }
+  </script>
+</head>
+<body onkeydown="keyEvent(event)" onkeyup="metaKeyUp(event)">
+</body>
+</html>
+ +

浏览器 bugs 和 quirks

+ +

键盘事件中有两个可用的属性keyCode 和 charCode。通常情况下,keyCode 指向的是用户按下的键盘上的那个键,而charCode 存储的是相应键的 ASCII 码值。这两个值不一定相同,如, 小写 'a' 和 大写 'A' 拥有相同的 keyCode,因为用户按下的是相同的按键,但是他们的charCode不同,因为两个字母的码值不同。 

+ +

不同浏览器对于charCode的处理方式并不统一。例如Internet Explorer 和Opera 并不支持 charCode,他们把字母信息写到了keyCode中,而且只在 onkeypress下有效。在 Onkeydown 和Onkeyup的事件中, keyCode 存储的仍然是按键的相关信息。 Firefox 则使用 "which", 来区分字母。.

+ +

可以到 Mozilla 文档 Keyboard Events 去了解关于键盘事件的更多信息。.

+ +

{{ draft() }}

+ +

举例:拖曳图片

+ +

下面的例子展示了firefox浏览器下如何实现拖动图片:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<style type='text/css'>
+img { position: absolute; }
+</style>
+
+<script type='text/javascript'>
+window.onload = function() {
+
+  movMeId=document.getElementById("ImgMov");
+  movMeId.style.top = "80px";
+  movMeId.style.left = "80px";
+  movMeId.style.position = "absolute";
+
+  document.onmousedown = coordinates;
+  document.onmouseup=mouseup;
+
+  function coordinates(e) {
+    if (e == null) { e = window.event;}
+    var sender = (typeof( window.event ) != "undefined" ) ? e.srcElement : e.target;
+
+    if (sender.id=="ImgMov") {
+      mouseover = true;
+      pleft = parseInt(movMeId.style.left);
+      ptop = parseInt(movMeId.style.top);
+      xcoor = e.clientX;
+      ycoor = e.clientY;
+      document.onmousemove=moveImage;
+      return false;
+    } else {
+        return false;
+    }
+  }
+
+  function moveImage(e) {
+    if (e == null) { e = window.event; }
+    movMeId.style.left = pleft+e.clientX-xcoor+"px";
+    movMeId.style.top = ptop+e.clientY-ycoor+"px";
+    return false;
+  }
+
+  function mouseup(e) {
+    document.onmousemove = null;
+  }
+}
+</script>
+</head>
+
+<body>
+  <img id="ImgMov" src="http://mozcom-cdn.mozilla.net/img/covehead/about/logo/download/logo-only.png" width="64" height="64"/>
+  <p>Drag and drop around the image in this page.</p>
+</body>
+
+</html>
+ +

举例:改变大小

+ +
{{todo("Need Content. Or, remove headline")}}
+ +

举例:绘制直线

+ +
+

附加文档信息

+ + +
+ +

 

diff --git a/files/zh-cn/web/javascript/javascript_technologies_overview/index.html b/files/zh-cn/web/javascript/javascript_technologies_overview/index.html new file mode 100644 index 0000000000..9dcb7b2e5a --- /dev/null +++ b/files/zh-cn/web/javascript/javascript_technologies_overview/index.html @@ -0,0 +1,96 @@ +--- +title: JavaScript 技术概览 +slug: Web/JavaScript/JavaScript_technologies_overview +tags: + - DOM + - JavaScript + - 入门 + - 新手 +translation_of: Web/JavaScript/JavaScript_technologies_overview +--- +
{{JsSidebar("Introductory")}}
+ +

介绍

+ +

HTML 定义网页的结构与内容,CSS 定义其格式与样式,而 JavaScript 则为网页增加可交互性,创作功能丰富的 Web 应用。

+ +

但是,如果从浏览器的范畴去理解“JavaScript”这个术语,它包含了截然不同的两个方面。一方面是 JavaScript 的核心语言(ECMAScript),另一方面是大量的 Web API 们,包括 DOM(文档对象模型)。

+ +

JavaScript 核心语言(ECMAScript)

+ +

JavaScript 的核心语言是 ECMAScript。ECMAScript 是一门由 ECMA TC39 委员会标准化的编程语言。

+ +

该核心语言同样可以被用在非浏览器环境之中,例如 node.js

+ +

哪些内容被纳入 ECMAScript 范畴之中?

+ +

除却一些其他元素,ECMAScript 定义了:

+ + + +

浏览器支持

+ +

As of October 2016, the current versions of the major Web browsers implement ECMAScript 5.1 and ECMAScript 2015, but older versions (still in use) implement ECMAScript 5 only.

+ +

截止 2014 年 8 月份,主流浏览器的最新版本都已经支持 ECMAScript 5.1,但是旧版本的浏览器大多仅支持 ECMAScript 3 和 ECMAScript 5 的部分标准。这里是一些关于 ECMAScript 5 的浏览器支持情况的资料。如今,主流浏览器的最新版本已经支持 ECMAScript 6 的大部分标准。

+ +

未来

+ +

The major 6th Edition of ECMAScript was officially approved and published as a standard on June 17, 2015 by the ECMA General Assembly. Since then ECMAScript Editions are published on a yearly basis.

+ +

ECMA-262(ECMAScript 4 或者 ES4)第4版的提议本应成为自1999年第3版发布以来的一次重要更新,但是在2008年8月份,ECMAScript第4版被回退到一个代号为ECMAScript Harmony的项目,像const关键字以及对象代理等内容都被涵盖其中。你可以在这里跟踪这个项目的进展。ECMA 委员会已经在 2015年6月17号,正式发布了第6版标准。

+ +

国际化 API

+ +

由 ECMA TC39 进行标准化的ECMAScript 国际化 API 规范是在 ECMAScript 语言规范之上额外增加的。国际化 API 为 JavaScript 提供了国际化的规则排序(字符串比较)、数字格式化、日期时间格式化等功能,能够让应用选择语言,并根据实际需要选用功能。本标准在 2012 年 12 月审批通过,可以在 MDN 的 {{jsxref("Intl")}} 页面查看各个浏览器对其的实现情况。The Internationalization specification is nowadays also ratified on a yearly basis and browsers constantly improve their implementation.

+ +

DOM API

+ +

WebIDL

+ +

WebIDL 规范定义了 ECMAScript 和 DOM 技术之间的交互规范。

+ +

DOM 的核心

+ +

文档对象模型(DOM)是用来表达 HTML、XHTML 及 XML 文档中的对象或与其进行交互的约定,它是跨平台的,并且与编程语言无关。通过调用DOM树上对象的方法可以操纵这些对象。文档对象模型核心是由  {{glossary("W3C")}} 进行标准化的,它将 HTML 和 XML 文档抽象成对象,并在其上定义接口以及操纵这些对象的机制,DOM 定义的元素有:

+ + + +

从 ECMAScript 的角度来看,DOM 规范中定义的对象被称作“宿主对象”。

+ +

HTML DOM

+ +

HTML,Web 的标记语言,是根据 DOM 定义的。位于 DOM 核心抽象概念之上,HTML 还定义了元素的意义。比如元素的 className 属性以及例如 {{domxref("document.body")}} 这样的 API。

+ +

HTML规范同时还约束了元素之间的关系,例如无序列表 {{htmlelement("ul")}} 元素中,只能以 {{htmlelement("li")}} 元素作为子元素来表达列表项。还有就是禁止使用标准中未定义的元素和属性。

+ +

想了解更多关于 {{domxref("Document")}} 对象、{{domxref("Window")}} 对象以及其他DOM元素的信息?请访问 MDN 的 DOM 文档

+ +

其他值得关注的 API

+ + + +

DOM 浏览器支持

+ +
相信每个 Web 开发人员都曾经有过“DOM就是一团糟”的体验,因为浏览器对 DOM 的支持千差万别。造成这种局面的主要原因是DOM 规范并未清晰定义很多重要的 DOM 特性。另外,一些浏览器也增加了不兼容的特性(例如 Intenet Explorer 的事件模型)。自 2011 年 6 月以来,W3C,特别是 WHATWG 都在对旧特性进行细节定义,以提高互通性。浏览器也在基于这些更加详细的规范改善它们的实现方式。
+ +

要实现跨浏览器的兼容性,一个常见的但可能不是最可靠的方式就是使用 JavaScript 库。这些库对于 DOM 特性进行抽象,以确保它们所提供的 API 在不同的浏览器上行为一致。被广泛采用的框架有 jQueryprototypeYUI

diff --git a/files/zh-cn/web/javascript/language_resources/index.html b/files/zh-cn/web/javascript/language_resources/index.html new file mode 100644 index 0000000000..3c23953433 --- /dev/null +++ b/files/zh-cn/web/javascript/language_resources/index.html @@ -0,0 +1,111 @@ +--- +title: JavaScript资源 +slug: Web/JavaScript/Language_Resources +tags: + - JavaScript +translation_of: Web/JavaScript/Language_Resources +--- +
{{JsSidebar}}
+ +

ECMAScript是形成JavaScript语言基础的脚本语言。ECMAScript是由Ecma国际标准组织以ECMA-262和ECMA-402规范的形式进行标准化的。下面的ECMAScript标准已经通过批准:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范名称文档链接颁布日期描述
最新版本
ECMA-262 Edition 6PDF, HTML2015年6月ECMAScript 2015 (6th Edition),最新发布的规范文档。
ECMA-402 2.0PDF2015年6月ECMAScript国际化API 2.0。
过时/历史版本
ECMA-262PDF1997年6月最初的ECMAScript标准。
ECMA-262 Edition 2PDF1998年8月ECMAScript第二版规范;同时也是ISO 16262标准。
ECMA-262 Edition 3PDF1999年12月ECMAScript第三版规范;对应于JavaScript 1.5.
+ 也请查看errata
ECMA-262 Edition 5PDF2009年12月ECMAScript 5
+ 也请查看ES5 errataMozilla对ECMAScript 5的支持
ECMA-357PDF2004年6月ECMAScript for XML (E4X).
+ 也请查看E4X errata.
ECMA-357 Edition 2PDF2005年12月ECMAScript for XML (E4X).
ECMA-262 Edition 5.1PDF, HTML2011年6月This version is fully aligned with 3rd edition of the international standard ISO/IEC 16262:2011.
+ It includes ES5 errata fixes, no new features.
ECMA-402 1.0PDF, HTML2012年12月ECMAScript国际化API 1.0。
+ +

查看wikipedia ECMAScript entry 了解更多关于ECMAScript历史的信息。

+ +

你也可以通过ecmascript.org的公共wiki和es-discuss邮件列表参与或查看最新版本的规范制定工作,版本代号为"Harmony"。

+ +

实现引擎

+ + + +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/memory_management/index.html b/files/zh-cn/web/javascript/memory_management/index.html new file mode 100644 index 0000000000..e7a4852337 --- /dev/null +++ b/files/zh-cn/web/javascript/memory_management/index.html @@ -0,0 +1,181 @@ +--- +title: 内存管理 +slug: Web/JavaScript/Memory_Management +tags: + - JavaScript + - 内存 + - 性能 +translation_of: Web/JavaScript/Memory_Management +--- +

{{JsSidebar("Advanced")}}

+ +

简介

+ +

像C语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()free()。相反,JavaScript是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。 释放的过程称为垃圾回收。这个“自动”是混乱的根源,并让JavaScript(和其他高级语言)开发者错误的感觉他们可以不关心内存管理。 

+ +

内存生命周期

+ +

不管什么程序语言,内存生命周期基本是一致的:   

+ +
    +
  1. 分配你所需要的内存
  2. +
  3. 使用分配到的内存(读、写)
  4. +
  5. 不需要时将其释放\归还
  6. +
+ +

所有语言第二部分都是明确的。第一和第三部分在底层语言中是明确的,但在像JavaScript这些高级语言中,大部分都是隐含的。

+ +

JavaScript 的内存分配

+ +

值的初始化

+ +

为了不让程序员费心分配内存,JavaScript 在定义变量时就完成了内存分配。

+ +
var n = 123; // 给数值变量分配内存
+var s = "azerty"; // 给字符串分配内存
+
+var o = {
+  a: 1,
+  b: null
+}; // 给对象及其包含的值分配内存
+
+// 给数组及其包含的值分配内存(就像对象一样)
+var a = [1, null, "abra"];
+
+function f(a){
+  return a + 2;
+} // 给函数(可调用的对象)分配内存
+
+// 函数表达式也能分配一个对象
+someElement.addEventListener('click', function(){
+  someElement.style.backgroundColor = 'blue';
+}, false);
+
+ +

通过函数调用分配内存

+ +

有些函数调用结果是分配对象内存:

+ +
var d = new Date(); // 分配一个 Date 对象
+
+var e = document.createElement('div'); // 分配一个 DOM 元素
+
+ +

有些方法分配新变量或者新对象:

+ +
var s = "azerty";
+var s2 = s.substr(0, 3); // s2 是一个新的字符串
+// 因为字符串是不变量,
+// JavaScript 可能决定不分配内存,
+// 只是存储了 [0-3] 的范围。
+
+var a = ["ouais ouais", "nan nan"];
+var a2 = ["generation", "nan nan"];
+var a3 = a.concat(a2);
+// 新数组有四个元素,是 a 连接 a2 的结果
+
+ +

使用值

+ +

使用值的过程实际上是对分配内存进行读取与写入的操作。读取与写入可能是写入一个变量或者一个对象的属性值,甚至传递函数的参数。

+ +

当内存不再需要使用时释放

+ +

大多数内存管理的问题都在这个阶段。在这里最艰难的任务是找到“哪些被分配的内存确实已经不再需要了”。它往往要求开发人员来确定在程序中哪一块内存不再需要并且释放它。

+ +

高级语言解释器嵌入了“垃圾回收器”,它的主要工作是跟踪内存的分配和使用,以便当分配的内存不再使用时,自动释放它。这只能是一个近似的过程,因为要知道是否仍然需要某块内存是无法判定的(无法通过某种算法解决)。

+ +

垃圾回收

+ +

如上文所述自动寻找是否一些内存“不再需要”的问题是无法判定的。因此,垃圾回收实现只能有限制的解决一般问题。本节将解释必要的概念,了解主要的垃圾回收算法和它们的局限性。

+ +

引用

+ +

垃圾回收算法主要依赖于引用的概念。在内存管理的环境中,一个对象如果有访问另一个对象的权限(隐式或者显式),叫做一个对象引用另一个对象。例如,一个Javascript对象具有对它原型的引用(隐式引用)和对它属性的引用(显式引用)。

+ +

在这里,“对象”的概念不仅特指 JavaScript 对象,还包括函数作用域(或者全局词法作用域)。

+ +

引用计数垃圾收集

+ +

这是最初级的垃圾收集算法。此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。

+ +

示例

+ +
var o = {
+  a: {
+    b:2
+  }
+};
+// 两个对象被创建,一个作为另一个的属性被引用,另一个被分配给变量o
+// 很显然,没有一个可以被垃圾收集
+
+
+var o2 = o; // o2变量是第二个对“这个对象”的引用
+
+o = 1;      // 现在,“这个对象”只有一个o2变量的引用了,“这个对象”的原始引用o已经没有
+
+var oa = o2.a; // 引用“这个对象”的a属性
+               // 现在,“这个对象”有两个引用了,一个是o2,一个是oa
+
+o2 = "yo"; // 虽然最初的对象现在已经是零引用了,可以被垃圾回收了
+           // 但是它的属性a的对象还在被oa引用,所以还不能回收
+
+oa = null; // a属性的那个对象现在也是零引用了
+           // 它可以被垃圾回收了
+
+ +

限制:循环引用

+ +

该算法有个限制:无法处理循环引用的事例。在下面的例子中,两个对象被创建,并互相引用,形成了一个循环。它们被调用之后会离开函数作用域,所以它们已经没有用了,可以被回收了。然而,引用计数算法考虑到它们互相都有至少一次引用,所以它们不会被回收。

+ +
function f(){
+  var o = {};
+  var o2 = {};
+  o.a = o2; // o 引用 o2
+  o2.a = o; // o2 引用 o
+
+  return "azerty";
+}
+
+f();
+
+ +

实际例子

+ +

IE 6, 7 使用引用计数方式对 DOM 对象进行垃圾回收。该方式常常造成对象被循环引用时内存发生泄漏:

+ +
var div;
+window.onload = function(){
+  div = document.getElementById("myDivElement");
+  div.circularReference = div;
+  div.lotsOfData = new Array(10000).join("*");
+};
+
+ +

在上面的例子里,myDivElement 这个 DOM 元素里的 circularReference 属性引用了 myDivElement,造成了循环引用。如果该属性没有显示移除或者设为 null,引用计数式垃圾收集器将总是且至少有一个引用,并将一直保持在内存里的 DOM 元素,即使其从DOM 树中删去了。如果这个 DOM 元素拥有大量的数据 (如上的 lotsOfData 属性),而这个数据占用的内存将永远不会被释放。

+ +

标记-清除算法

+ +

这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。

+ +

这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象……从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。

+ +

这个算法比前一个要好,因为“有零引用的对象”总是不可获得的,但是相反却不一定,参考“循环引用”。

+ +

从2012年起,所有现代浏览器都使用了标记-清除垃圾回收算法。所有对JavaScript垃圾回收算法的改进都是基于标记-清除算法的改进,并没有改进标记-清除算法本身和它对“对象是否不再需要”的简化定义。

+ +

循环引用不再是问题了

+ +
在上面的示例中,函数调用返回之后,两个对象从全局对象出发无法获取。因此,他们将会被垃圾回收器回收。第二个示例同样,一旦 div 和其事件处理无法从根获取到,他们将会被垃圾回收器回收。
+ +

限制: 那些无法从根对象查询到的对象都将被清除

+ +

尽管这是一个限制,但实践中我们很少会碰到类似的情况,所以开发者不太会去关心垃圾回收机制。

+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.1/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.1/index.html new file mode 100644 index 0000000000..968f518145 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.1/index.html @@ -0,0 +1,71 @@ +--- +title: JavaScript 1.1的新特性 +slug: Web/JavaScript/New_in_JavaScript/1.1 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.1 +--- +
{{jsSidebar("New_in_JS")}}
+ +

下面介绍的是JavaScript从Netscape Navigator 2.0到3.0的更新日志。旧的Netscape文档请参考"第1版之后新增的特性"。Netscape Navigator 3.0在1996年8月19发布,是支持JavaScript的浏览器的第二个主要的版本。

+ +

JavaScript 版本

+ +

Netscape Navigator 3.0 也引进了JavaScript语言的版本号。

+ +
<SCRIPT LANGUAGE="JavaScript">    <!-- JavaScript for Navigator 2.0. -->
+<SCRIPT LANGUAGE="JavaScript1.1"> <!-- JavaScript for Navigator 3.0. -->
+ +

JavaScript 1.1 新特性

+ +

新增的对象

+ + + +

新增的属性

+ + + +

新增的方法

+ + + +

新增的操作符

+ + + +

其他新特性

+ + + +

JavaScript 1.1修改的功能

+ + diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.2/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.2/index.html new file mode 100644 index 0000000000..17fde7ba38 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.2/index.html @@ -0,0 +1,89 @@ +--- +title: JavaScript 1.2的新特性 +slug: Web/JavaScript/New_in_JavaScript/1.2 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.2 +--- +
{{jsSidebar("New_in_JS")}}
+ +

下面介绍的是JavaScript从Netscape Navigator 3.0到4.0的更新日志。旧的Netscape文档可以在archive.org上面找到。Netscape Navigator 4.0在1997年6月11日发布,它是是支持JavaScript的浏览器的第三个主要的版本。

+ +

JavaScript 版本

+ +

Netscape Navigator 4.0将JavaScript语言的版本升到1.2。需要注意的是,Netscape Navigator 3.0以及更早的版本忽略了设置为"JavaScript 1.2"和更高的版本的脚本语言属性。

+ +
<SCRIPT LANGUAGE="JavaScript1.1"> <!-- JavaScript for Navigator 3.0. -->
+<SCRIPT LANGUAGE="JavaScript1.2"> <!-- JavaScript for Navigator 4.0. -->
+ +

JavaScript 1.2新特性

+ +

新增的对象

+ + + +

新增的属性

+ + + +

新增的方法

+ + + +

新增的操作符

+ + + +

新增的语句

+ + + +

其他新特性

+ + + +

JavaScript 1.2修改的功能

+ + diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.3/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.3/index.html new file mode 100644 index 0000000000..193d5156d8 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.3/index.html @@ -0,0 +1,138 @@ +--- +title: JavaScript 1.3的新特性 +slug: Web/JavaScript/New_in_JavaScript/1.3 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.3 +--- +
{{jsSidebar("New_in_JS")}}
+ +

下面介绍的是JavaScript从Netscape Navigator 4.0到4.5的更新日志。旧的Netscape文档可以在archive.org上面找到。Netscape Navigator 4.5是在1998年10月19日发布的。

+ +

JavaScript 1.3 最显著的变化是通过消除JavaScript1.2和1997年6月发布的新ECMA标准的不一致性来遵守ECMA-262和Unicode。JavaScript 1.2附加的特性,在ECMA-262的规定外还保留在JavaScript语言(见下面的列表中的差异)。

+ +

JavaScript 版本

+ +

Netscape Navigator 4.06 到 4.5 将JavaScript语言的版本升到1.3。需要注意的是,Netscape Navigator 4.0 到 4.05以及更早的版本忽略了设置为"JavaScript 1.3"和更高的版本的脚本语言属性。

+ +
<SCRIPT LANGUAGE="JavaScript1.2"> <!-- JavaScript for Navigator 4.0. -->
+<SCRIPT LANGUAGE="JavaScript1.3"> <!-- JavaScript for Navigator 4.5. -->
+ +

JavaScript 1.3新特性

+ +

新增的全局变量

+ + + +

新增的方法

+ + + +

其他新特性

+ + + +

JavaScript 1.3 修改的功能

+ + + +

非ECMA-262规范的JavaScript 1.3特性

+ +

下面是关于1998年6月的ECMA-262版本和JavaScript 1.3之间的比较。下面的特性不是当时的标准的一部分,但是在JavaScript 1.3里面实施了。

+ +

关键字和操作符

+ + + +

语句

+ + + +

内置对象

+ + + +

内置对象的方向

+ + diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.4/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.4/index.html new file mode 100644 index 0000000000..a76c4f5424 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.4/index.html @@ -0,0 +1,25 @@ +--- +title: JavaScript 1.4的新特性 +slug: Web/JavaScript/New_in_JavaScript/1.4 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.4 +--- +
{{jsSidebar("New_in_JS")}}
+ +

下面是 JavaScript 1.4 的更新记录,它只可用于 1999 年发布的 Netscape 服务端 JavaScript。 旧的 Netscape 文档可在 archive.org 找到。

+ +

JavaScript 1.4的新特性

+ + + +

JavaScript 1.4的功能改动

+ + diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.5/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.5/index.html new file mode 100644 index 0000000000..0375ad3f7f --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.5/index.html @@ -0,0 +1,42 @@ +--- +title: JavaScript 1.5 的新特性 +slug: Web/JavaScript/New_in_JavaScript/1.5 +tags: + - JavaScript + - 版本 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.5 +--- +
{{jsSidebar("New_in_JS")}}
+ +

以下为JavaScript 1.5 的更新日志。该版本包含在发行于2000年11月14日的Netscape Navigator 6.0中,也在后续的的Netscape Navigator版本和Firefox 1.0中使用。你可以拿JavaScript 1.5 和JScript version 5.5,Internet Explorer 5.5进行比较,后者发行于2000年7月。相应的ECMA 标准是 ECMA-262 Edition 3版 (自1999年12月)。

+ +

JavaScript 1.5 新特性

+ + + +

JavaScript 1.5 功能变化

+ + + +

 

diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.6/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.6/index.html new file mode 100644 index 0000000000..928fd75334 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.6/index.html @@ -0,0 +1,35 @@ +--- +title: JavaScript 1.6 的新特性 +slug: Web/JavaScript/New_in_JavaScript/1.6 +tags: + - JavaScript + - 版本 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.6 +--- +
+
{{jsSidebar("New_in_JS")}}
+ +

以下是JavaScript 1.6的更新日志。JavaScript 1.6已经被包含在2005年11月发布的Firefox 1.5 (Gecko 1.8)中。JavaScript 1.6相对应的ECMA标准是ECMA-262第3版和ECMAScript for XML (E4X),这让它拥有了一些额外的特性 。引入了一些新特性:E4X,几个新的数组方法,还数组字符串的通用接口(generics)

+ +

JavaScript 1.6新特性

+ + + +

JavaScript 1.6功能变化

+ + +
diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.7/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.7/index.html new file mode 100644 index 0000000000..e268345ca5 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.7/index.html @@ -0,0 +1,40 @@ +--- +title: JavaScript 1.7 的新特性 +slug: Web/JavaScript/New_in_JavaScript/1.7 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.7 +--- +
{{jsSidebar("New_in_JS")}}
+ +
 
+ +
以下是javaScript 1.7版本的更新日志,这个版本被包括在 Firefox 2 (2006年10月)。
+ +

 

+ +

JavaScript 1.7是一个引出了一些新特性的语言更新,尤其是generator,iterator,数组推导式, let 表达式和解构赋值。

+ +

使用 JavaScript 1.7

+ +

为了使用 JavaScript 1.7的一些新特性,你需要明确指出你希望使用 JavaScript 1.7。在HTML 或XUL code中,使用:

+ +
<script type="application/javascript;version=1.7"></script>
+
+ +

当使用 JavaScript shell的时候,你需要用 -version 170 开启命令行或者用version() 函数来设置你想使用的JavaScript版本。

+ +
version(170);
+
+ +

你需要指定1.7版本来使用新的“yield”和“let”关键字,因为现存的代码可能用它们当变量或者函数名用。没有涉及到新关键词的特性(比如解构赋值和数组推导式)可以直接使用,而不需要指明JavaScript版本。

+ +

JavaScript 1.7的新特性

+ +

以下JavaScript 1.7的新特性目前还不是ECMA-262标准的一部分。在最近的Firefox版本中会根据ECMAScipt6中的描述来实现这些功能。具体内容见这些参考页面。

+ + diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.8.1/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.8.1/index.html new file mode 100644 index 0000000000..9ca99c06af --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.8.1/index.html @@ -0,0 +1,29 @@ +--- +title: JavaScript 1.8.1 的新特性 +slug: Web/JavaScript/New_in_JavaScript/1.8.1 +tags: + - Firefox 3.5 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.8.1 +--- +
{{jsSidebar("New_in_JS")}}
+ +

下面是JavaScript 1.8.1 的更新内容. 该版本已包含在 Firefox 3.5 中.

+ +

JavaScript 1.8.1 是在语义上有适度更新的版本; 其主要更新是添加能够提升性能的Tracemonkey即时编译器

+ +

JavaScript 1.8.1 新特性

+ + + +

JavaScript 1.8.1 功能更新

+ + diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.8.5/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.8.5/index.html new file mode 100644 index 0000000000..a61a892e70 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.8.5/index.html @@ -0,0 +1,122 @@ +--- +title: JavaScript 1.8.5 的新特性 +slug: Web/JavaScript/New_in_JavaScript/1.8.5 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.8.5 +--- +
{{jsSidebar("New_in_JS")}}
+ +

下面的内容是JavaScript 1.8.5的更新记录. 该版本已包含在Firefox 4中.

+ +

JavaScript 1.8.5的新特性

+ +

新函数

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionDescription
Object.create()使用指定的原型对象和属性. {{bug("492840")}}
Object.defineProperty()为对象添加给定的描述信息的属性名.
Object.defineProperties()为对象添加多个给定的描述信息的属性名.
Object.getOwnPropertyDescriptor()返回对象的指定属性名的描述信息. {{bug("505587")}}
Object.keys()返回由对象的所有可枚举属性组成的数组. {{bug("307791")}}
Object.getOwnPropertyNames()返回由对象的所有可枚举和不可枚举属性组成的数组. {{bug("518663")}}
Object.preventExtensions()防止对象进行任意的扩展. {{bug("492849")}}
Object.isExtensible()判断对象是否可以扩展. {{bug("492849")}}
Object.seal()防止其他代码删除对象的属性. {{bug("492845")}}
Object.isSealed()判断对象是否是密封(即禁止删除属性)的. {{bug("492845")}}
Object.freeze()冻结一个对象: 其他代码不能删除或修改任何属性. {{bug("492844")}}
Object.isFrozen()判断对象是否是冻结的. {{bug("492844")}}
Array.isArray()判断变量是否是数组. {{bug("510537")}}
Date.prototype.toJSON()返回一个Date对象用JSON格式化的字符串.
Function.prototype.bind()创建一个新函数,当这个函数被调用时,函数会使用提供的上下文环境(给定的字符序列) {{bug("429507")}}
+ +

ECMAScript5新特性

+ + + +

其他标准化的工作

+ +

删除一些定义getters和setters的非标准化语法; ECMAScript 5 定义的语法没有变化. 这些语法很难懂且很少被使用; 如果这个影响到你, 详细内容请看 这篇博客.

+ +

新对象

+ + + + + + + + + + + + + + +
ObjectDescription
Proxy提供创建对象和函数的代理,以在Javascript中支持元编程.
+ +

JavaScript 1.8.5中功能变化

+ + diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.8/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.8/index.html new file mode 100644 index 0000000000..d69d021c25 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/1.8/index.html @@ -0,0 +1,39 @@ +--- +title: New in JavaScript 1.8 +slug: Web/JavaScript/New_in_JavaScript/1.8 +tags: + - JavaScript + - 版本 +translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.8 +--- +
{{jsSidebar("New_in_JS")}}
+ +

以下为JavaScript 1.8的更新日志。JavaScript 1.8 是 Gecko 1.9(已合并在 Firefox 3 中)的一部分。参见 {{ Bug("380236") }} 以跟踪 JavaScript 1.8。

+ +

使用 JavaScript 1.8

+ +

为了可以在 HTML 中使用 JavaScript 1.8 的新特性,需要这样写:

+ +
 <script type="application/javascript;version=1.8"> ... 你的代码 ... </script>
+
+ +

另一种方法(不推荐)是使用旧式的 <script> 属性 language,把它定义为 "JavaScript1.8"。

+ +

在使用 JavaScript shell 、JavaScript XPCOM 组件,或者 XUL <script> 元素的时候,将自动启用最新的JS版本(Mozilla 1.9中的 JS1.8)({{ Bug("381031") }}, {{ Bug("385159") }})。

+ +

如果需要使用新的关键字 "yield" 和 "let",你需要指定是1.7版本或者更高的版本,因为现有的代码可能会把这两个关键字用作变量名或者函数名。如果要使用的新特性没有引入任何新的关键字(例如生成器表达式),就可以不指定 JavaScript 的版本。

+ +

JavaScript 1.8新特性

+ + + +

JavaScript 1.8功能更新

+ +

对for..in解构的修改

+ +

JavaScript1.8中的一个修改是对JavaScript1.7中引入的数组键值结构相关的bug修复。之前可以用for ( var [key, value] in array )的方式来解构一个数组的键值。但是,这也让对数组的数组的键值解构变得不可能(比如一个迭代器返回一个当前键值对的数组)。现在这个问题可以用for ( var [key, value] in Iterator(array))来解决({{ Bug("366941") }})。

diff --git a/files/zh-cn/web/javascript/new_in_javascript/ecmascript_5_support_in_mozilla/index.html b/files/zh-cn/web/javascript/new_in_javascript/ecmascript_5_support_in_mozilla/index.html new file mode 100644 index 0000000000..2dc69205cb --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/ecmascript_5_support_in_mozilla/index.html @@ -0,0 +1,41 @@ +--- +title: ECMAScript 5 support in Mozilla +slug: Web/JavaScript/New_in_JavaScript/ECMAScript_5_support_in_Mozilla +translation_of: Archive/Web/JavaScript/New_in_JavaScript/ECMAScript_5_support_in_Mozilla +--- +
{{jsSidebar("New_in_JS")}}
+ +

ECMAScript 5.1, an older version of the standard upon which JavaScript is based, was approved in June 2011.

+ +

The JavaScript runtime used in the latest versions of Mozilla projects including both Firefox and Thunderbird has full support for ECMAScript 5.1 features. This article covers the features supported by different versions of Mozilla's JavaScript runtime.

+ +

Supported features

+ +

Added in JavaScript 1.8.5 (Gecko 2, Firefox 4 and later)

+ +

Firefox 4 has full ECMAScript 5 support including the Object.* methods and strict mode. See New in JavaScript 1.8.5.

+ +

Added in JavaScript 1.8.1 (Gecko 1.9.1, Firefox 3.5)

+ + + +

Improvements laid out by ECMAScript 5 have been made in the parsing algorithm that prevents evaluating XHTML as JavaScript code in certain circumstances.

+ +

Added in JavaScript 1.6 (Gecko 1.8, Firefox 1.5)

+ +

New Array methods offering several improved methods for manipulating arrays -- have been part of JavaScript since JavaScript 1.6. Now they've been standardized as part of ECMAScript 5.

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/new_in_javascript/ecmascript_6_support_in_mozilla/index.html b/files/zh-cn/web/javascript/new_in_javascript/ecmascript_6_support_in_mozilla/index.html new file mode 100644 index 0000000000..25210c32b2 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/ecmascript_6_support_in_mozilla/index.html @@ -0,0 +1,282 @@ +--- +title: Mozilla 对 ECMAScript 6 的支持 +slug: Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla +tags: + - ECMAScript2015 + - ECMAScript6 + - Firefox + - JavaScript +translation_of: Archive/Web/JavaScript/New_in_JavaScript/ECMAScript_2015_support_in_Mozilla +--- +
+
{{jsSidebar("New_in_JS")}}
+ +

ECMAScript 2015 (6th Edition)是目前 ECMAScript 语言规范的标准。通常被称为"ES2015",在SpiderMonkey 中它规定了 JavaScript 的实现标准,SpiderMonkey 是一个 JavaScript 引擎,被广泛用于火狐浏览器等谋智的众多产品中。

+ +

"ES.next" 的第一份工作草案 (基于 ECMAScript 5.1) 发布于 2011 年 7 月 12 日,代号为 "ES.next" 或 "Harmony"。2014 年 8 月,ECMAScript 2015 草案规范停止增加新的功能,开始进入稳定期与 bug 修复阶段。最终,ECMA-262 Edition 6 于 2015 年 6 月 17 日由 ECMA 联合大会 (ECMA General Assembly) 作为标准正式发布。它同时也是国际工业标准 ISO/IEC 16262:2016。

+ +

你可以通过 ecma-international.org 免费下载规范的 PDFHTML 版本。

+ +

es-discuss 是 ECMAScript 规范的讨论与反馈渠道。

+ +

Firefox 已经支持的特性

+ +

这里列出的功能已经在 Firefox 中支持;每个特性后面标注了具体实现的浏览器版本。

+ +

标准库

+ +

Array 对象的补充

+ + + +

新的 Map 和 Set,以及 WeakMap 和 WeakSet 对象

+ + + +

新的 Math 方法

+ + + +

Number 对象的补充

+ + + +

Object 对象的补充

+ + + +

Date 对象的补充

+ + + +

新的 Promise 对象

+ + + +

新的 Reflect 对象

+ + + +

RegExp 对象的补充

+ + + +

String 对象的补充

+ + + +

新的 Symbol 对象

+ + + +

Typed Arrays

+ +

Typed arrays 已经合并到 ECMAScript 2015 中,不再具有自己单独的规范

+ + + +

表达式和操作符

+ + + + + +

语句

+ + + +

函数

+ + + +

其他特性

+ + + +

和 ES2015 规范不兼容的特性

+ +

Firefox (部分)实现了以下特性,但是与规范不兼容。原因有如下几个:Firefox 是依据 ES 6 规范的早期草案来实现,或者 Firefox 是作为实验性特性来实现,而当时与之类似的特性还没有被添加到 ES2015 规范中。

+ + + +

相关链接

+ + +
diff --git a/files/zh-cn/web/javascript/new_in_javascript/index.html b/files/zh-cn/web/javascript/new_in_javascript/index.html new file mode 100644 index 0000000000..95eee26559 --- /dev/null +++ b/files/zh-cn/web/javascript/new_in_javascript/index.html @@ -0,0 +1,99 @@ +--- +title: JavaScript更新 +slug: Web/JavaScript/New_in_JavaScript +tags: + - ECMAScript + - ECMAScript 2017 + - JavaScript + - 版本 +translation_of: Archive/Web/JavaScript/New_in_JavaScript +--- +
{{jsSidebar("New_in_JS")}}
+ +
 
+ +

本章包含有关JavaScript版本历史记录的信息,以及基于Mozilla/SpiderMonkey-的JavaScript应用程序的实现状态,例如Firefox。

+ +

ECMAScript版本

+ +
+
语言资源
+
在这里学习更多的JavaScript的标准ECMAScript。
+
ECMAScript 5的支持情况
+
Mozilla 的引擎和产品 对于标准ECMA-262 Edition 5.1的支持情况。
+
ECMAScript 2015的支持情况
+
Mozilla 的引擎和产品对于标准ECMA-262 Edition 6的支持情况。
+
ECMAScript 2016的支持情况
+
Mozilla 的引擎和产品对于即将到来的ECMA-262 Edition 7的支持情况.
+
+ +

JavaScript发布说明

+ +
+
Firefox中的JavaScript更新日志
+
Firefox 5以及以后版本的JavaScript日志更新情况。
+
Chrome中的JavaScript更新日志
+
Chrome中的JavaScript日志更新情况。
+
+ +

JavaScript版本

+ +

弃用项 ({{deprecated_inline()}})。这里面是一些已经确定的弃用的api以及一下Mozilla组织专用的API  正在被慢慢的弃用不建议使用。Firefox 4 所用的javascirpt引擎是 ECMAScript(1.8.5). 就像现在我们提到的新的引擎 ECMA-262 里面的标准都在 ECMAScript 2015 里面的实现了API。

+ +

JavaScript于1996年3月在Netscape Navigator 2.0和Internet Explorer 2.0中发布为1.0版。

+ +
+
JavaScript 1.1
+
该版本在Netscape Navigator 3.0中使用。发布于1996年8月19日。
+
JavaScript 1.2
+
该版本在Netscape Navigator 4.0-4.05中使用。发布于1997年6月11日。
+
JavaScript 1.3
+
该版本在Netscape Navigator 4.06-4.7x中使用。发布于1998年10月19日。符合ECMA-262第1版和第2版的标准
+
JavaScript 1.4
+
版本在Netscape的服务器端发送的JavaScript。于1999年发行。
+
JavaScript 1.5
+
该版本在Netscape Navigator 6.0和Firefox 1.0中使用。发布于2000年11月14日。符合ECMA-262第3版的标准
+
JavaScript 1.6
+
该版本在 Firefox 1.5中使用。发布于2005年11月。加入了ECMAScript标准的XML(E4X),Array方法,String以及泛型
+
JavaScript 1.7
+
Version shipped in Firefox 2. Released in October 2006.
+ Includes generators, iterators, array comprehensions, let expressions, and destructuring assignment.
+
JavaScript 1.8
+
Version shipped in Firefox 3. Released in June 2008.
+
包括表达式闭包,生成器表达式和Array.reduce()
+
JavaScript 1.8.1
+
Version shipped in Firefox 3.5. Released on June 30, 2009.
+
包括TraceMonkey JIT并原生支持JSON。
+
JavaScript 1.8.2
+
Version shipped in Firefox 3.6. Released June 22, 2009.
+ Includes only minor changes.
+
JavaScript 1.8.5
+
Version shipped in Firefox 4. Released July 27, 2010.包括符合ECMA-262 Edition 5的许多新功能。 这是最后一个JavaScript版本。
+
ES2015
+
+ + + +

ES2016

+ + + +

ES2017

+ + + +

 

+ +

 

diff --git a/files/zh-cn/web/javascript/reference/about/index.html b/files/zh-cn/web/javascript/reference/about/index.html new file mode 100644 index 0000000000..9233514593 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/about/index.html @@ -0,0 +1,52 @@ +--- +title: 关于该参考 +slug: Web/JavaScript/Reference/About +tags: + - JavaScript +translation_of: Web/JavaScript/Reference/About +--- +
{{JsSidebar}}
+ +

该JavaScript参考提供Javascript语言的知识仓库。 详细的描述了完整的Javascript语言的信息。如果你编写JavaScript代码, 你会经常使用这些页面 (因此标题为 "JavaScript参考文档")。如果你正在学习JavaScript, 或需要帮助理解一些Javascript的功能或特性, 请查看 JavaScript指南

+ +

JavaScript 语言正打算在更大的环境中使用,如浏览器,服务端脚本,以及类似环境中。大多数情况下, 该参考的内容试图保证与目标浏览器环境无关。

+ +

哪里查找 JavaScript 信息

+ +

JavaScript 核心语言特性的文档 (绝大部分基于 ECMAScript ) 包含如下:

+ + + +

如果你是Javascript新手,从指南开始. 当你有一定基础后, 可以开始使用参考文档 获取单个对象和语言构造的详情。

+ +

该参考的结构

+ +

JavaScript参考中你能发现如下的章节:

+ +
+
标准内置对象
+
该章节描述了所有的JavaScript标准内置对象, 及相关的方法和属性.
+
语句和声明
+
JavaScript应用由合适的语法的语句构成. 单条语句可以占用多行.多条语句也可能只占用一行,中间用分好分隔. 语句不是只有一个关键词,而是由一组关键词组成.
+
表达式和运算符
+
该章节描述了所有的JavaScript 操作符运算符, 表达式和关键词。
+
函数
+
JavaScript函数的章节。
+
+
该章节介绍了ECMAScript 6中的类。
+
错误
+
该章节描述了JavaScript运行时可能抛出的错误、异常和警告。
+
JavaScript更新
+
JavaScript 版本历史的章节.
+
+ +

更多参考页面

+ + diff --git a/files/zh-cn/web/javascript/reference/classes/class_elements/index.html b/files/zh-cn/web/javascript/reference/classes/class_elements/index.html new file mode 100644 index 0000000000..fb8c618a9b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/classes/class_elements/index.html @@ -0,0 +1,352 @@ +--- +title: 类元素 +slug: Web/JavaScript/Reference/Classes/Class_elements +tags: + - Class + - JavaScript + - 类 +translation_of: Web/JavaScript/Reference/Classes/Public_class_fields +--- +
{{JsSidebar("Classes")}}
+ +
公有(public)和私有(private)字段声明是一个JavaScript标准委员会TC39提议的试验性功能 (第3阶段)。这项功能在浏览器中的支持还受限,但你可以通过Babel等构建系统来使用它。参见下面的兼容性信息
+ +

公有字段

+ +

静态公有字段和实例公有字段都是可编辑的,可遍历的,可配置的。它们本身不同于私有对应值(private counterparts)的是,它们参与原型的继承。

+ +

静态公有字段

+ +

静态公有字段在你想要创建一个只在每个类里面只存在一份,而不会存在于你创建的每个类的实例中的属性时可以用到。你可以用它存放缓存数据、固定结构数据或者其他你不想在所有实例都复制一份的数据。

+ +

静态公有字段是使用关键字 static 声明的。我们在声明一个类的时候,使用Object.defineProperty方法将静态公有字段添加到类的构造函数中。在类被声明之后,可以从类的构造函数访问静态公有字段。

+ +
class ClassWithStaticField {
+  static staticField = 'static field';
+}
+
+console.log(ClassWithStaticField.staticField);
+// 预期输出值: "static field"​
+
+ +

没有设定初始化程序的字段将默认被初始化为undefined

+ +
class ClassWithStaticField {
+  static staticField;
+}
+
+console.assert(ClassWithStaticField.hasOwnProperty('staticField'));
+console.log(ClassWithStaticField.staticField);
+// 预期输出值: "undefined"
+ +

静态公有字段不会在子类里重复初始化,但我们可以通过原型链访问它们。

+ +
class ClassWithStaticField {
+  static baseStaticField = 'base field';
+}
+
+class SubClassWithStaticField extends ClassWithStaticField {
+  static subStaticField = 'sub class field';
+}
+
+console.log(SubClassWithStaticField.subStaticField);
+// 预期输出值: "sub class field"
+
+console.log(SubClassWithStaticField.baseStaticField);
+// 预期输出值: "base field"
+ +

当初始化字段时,this指向的是类的构造函数。你可以通过名字引用构造函数,并使用super获取到存在的超类构造函数。

+ +
class ClassWithStaticField {
+  static baseStaticField = 'base static field';
+  static anotherBaseStaticField = this.baseStaticField;
+
+  static baseStaticMethod() { return 'base static method output'; }
+}
+
+class SubClassWithStaticField extends ClassWithStaticField {
+  static subStaticField = super.baseStaticMethod();
+}
+
+console.log(ClassWithStaticField.anotherBaseStaticField);
+// 预期输出值: "base static field"
+
+console.log(SubClassWithStaticField.subStaticField);
+// 预期输出值: "base static method output"
+
+ +

公有实例字段

+ +

公有实例字段存在于类的每一个实例中。通过声明一个公有字段,我们可以确保该字段一直存在,而类的定义则会更加像是自我描述。

+ +

公有实例字段可以在基类的构造过程中(构造函数主体运行前)使用Object.defineProperty添加,也可以在子类构造函数中的super()函数结束后添加。

+ +
class ClassWithInstanceField {
+  instanceField = 'instance field';
+}
+
+const instance = new ClassWithInstanceField();
+console.log(instance.instanceField);
+// 预期输出值: "instance field"
+ +

没有设定初始化程序的字段将默认被初始化为undefined

+ +
class ClassWithInstanceField {
+  instanceField;
+}
+
+const instance = new ClassWithInstanceField();
+console.assert(instance.hasOwnProperty('instanceField'));
+console.log(instance.instanceField);
+// 预期输出值: "undefined"
+ +

和属性(properties)一样,字段名可以由计算得出。

+ +
const PREFIX = 'prefix';
+
+class ClassWithComputedFieldName {
+    [`${PREFIX}Field`] = 'prefixed field';
+}
+
+const instance = new ClassWithComputedFieldName();
+console.log(instance.prefixField);
+// 预期输出值: "prefixed field"
+ +

当初始化字段时,this指向的是类正在构造中的实例。和公共实例方法相同的是:你可以在子类中使用super来访问超类的原型。

+ +
class ClassWithInstanceField {
+  baseInstanceField = 'base field';
+  anotherBaseInstanceField = this.baseInstanceField;
+  baseInstanceMethod() { return 'base method output'; }
+}
+
+class SubClassWithInstanceField extends ClassWithInstanceField {
+  subInstanceField = super.baseInstanceMethod();
+}
+
+const base = new ClassWithInstanceField();
+const sub = new SubClassWithInstanceField();
+
+console.log(base.anotherBaseInstanceField);
+// 预期输出值: "base field"
+
+console.log(sub.subInstanceField);
+// 预期输出值: "base method output"
+ +

公共方法

+ +

静态公共方法

+ +

关键字static将为一个类定义一个静态方法。静态方法不会在实例中被调用,而只会被类本身调用。它们经常是工具函数,比如用来创建或者复制对象。

+ +

{{EmbedInteractiveExample("pages/js/classes-static.html")}}

+ + + +

静态方法是在类的赋值阶段用Object.defineProperty方法添加到类中的。静态方法是可编辑的、不可遍历的和可配置的。

+ +

公共实例方法

+ +

正如其名,公共实例方法是可以在类的实例中使用的。

+ +
class ClassWithPublicInstanceMethod {
+  publicMethod() {
+    return 'hello world';
+  }
+}
+
+const instance = new ClassWithPublicInstanceMethod();
+console.log(instance.publicMethod());
+// 预期输出值: "hello worl​d"
+ +

公共实例方法是在类的赋值阶段用Object.defineProperty方法添加到类中的。静态方法是可编辑的、不可遍历的和可配置的。

+ +

你可以使用生成器(generator)、异步和异步生成器方法。

+ +
class ClassWithFancyMethods {
+  *generatorMethod() { }
+  async asyncMethod() { }
+  async *asyncGeneratorMethod() { }
+}
+ +

在实例的方法中,this指向的是实例本身,你可以使用super访问到超类的原型,由此你可以调用超类的方法。

+ +
class BaseClass {
+  msg = 'hello world';
+  basePublicMethod() {
+    return this.msg;
+  }
+}
+
+class SubClass extends BaseClass {
+  subPublicMethod() {
+    return super.basePublicMethod();
+  }
+}
+
+const instance = new SubClass();
+console.log(instance.subPublicMethod());
+// 预期输出值: "hello worl​d"
+
+ +

gettersetter是和类的属性绑定的特殊方法,分别会在其绑定的属性被取值、赋值时调用。使用getset句法定义实例的公共gettersetter

+ +
class ClassWithGetSet {
+  #msg = 'hello world';
+  get msg() {
+    return this.#msg;
+  }
+  set msg(x) {
+    this.#msg = `hello ${x}`;
+  }
+}
+
+const instance = new ClassWithGetSet();
+console.log(instance.msg);
+// expected output: "hello worl​d"
+
+instance.msg = 'cake';
+console.log(instance.msg);
+// 预期输出值: "hello cake"
+
+ +

私有字段

+ +

静态私有字段

+ +

静态私有字段可以在类声明本身内部的构造函数上被访问到。

+ +

静态变量只能被静态方法访问的限制依然存在。

+ +
class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD;
+
+  static publicStaticMethod() {
+    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42;
+    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD;
+  }
+}
+
+assert(ClassWithPrivateStaticField.publicStaticMethod() === 42);
+ +

静态私有字段是在类赋值的时候被添加到类构造函数中的。

+ +

静态私有字段有一个来源限制。只有定义静态私有字段的类可以访问该字段。这在使用this时,可能会导致不符合预期的行为。

+ +
class BaseClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD;
+
+  static basePublicStaticMethod() {
+    this.#PRIVATE_STATIC_FIELD = 42;
+    return this.#PRIVATE_STATIC_FIELD;
+  }
+}
+
+class SubClass extends BaseClassWithPrivateStaticField { }
+
+assertThrows(() => SubClass.basePublicStaticMethod(), TypeError);
+
+ +

私有实例字段

+ +

私有实例字段是通过# names句型(读作“哈希名称”)声明的,即为识别符加一个前缀“#”。“#”是名称的一部分,也用于访问和声明。

+ +

封装是语言强制实施的。引用不在作用域内的 # names 是语法错误。

+ +
class ClassWithPrivateField {
+  #privateField;
+
+  constructor() {
+    this.#privateField = 42;
+    this.#randomField = 666; # Syntax error
+  }
+}
+
+const instance = new ClassWithPrivateField();
+instance.#privateField === 42; // Syntax error
+
+ +

私有方法

+ +

静态私有方法

+ +

和静态公共方法一样,静态私有方法也是在类里面而非实例中调用的。和静态私有字段一样,它们也只能在类的声明中访问。

+ +

你可以使用生成器(generator)、异步和异步生成器方法。

+ +

静态私有方法可以是生成器、异步或者异步生成器函数。

+ +
class ClassWithPrivateStaticMethod {
+    static #privateStaticMethod() {
+        return 42;
+    }
+
+    static publicStaticMethod() {
+        return ClassWithPrivateStaticMethod.#privateStaticMethod();
+    }
+}
+
+assert(ClassWithPrivateStaticMethod.publicStaticMethod() === 42);
+
+ +

私有实例方法

+ +

私有实例方法在类的实例中可用,它的访问方式的限制和私有实例字段相同。

+ +
class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world';
+  }
+
+  getPrivateMessage() {
+      return #privateMethod();
+  }
+}
+
+const instance = new ClassWithPrivateMethod();
+console.log(instance.getPrivateMessage());
+// 预期输出值: "hello worl​d"
+ +

私有实例方法可以是生成器、异步或者异步生成器函数。私有gettersetter也是可能的:

+ +
class ClassWithPrivateAccessor {
+  #message;
+
+  get #decoratedMessage() {
+    return `✨${this.#message}✨`;
+  }
+  set #decoratedMessage(msg) {
+    this.#message = msg;
+  }
+
+  constructor() {
+    this.#decoratedMessage = 'hello world';
+    console.log(this.#decoratedMessage);
+  }
+}
+
+new ClassWithPrivateAccessor();
+// 预期输出值: "✨hello worl​d✨"
+
+ +

浏览器兼容性

+ +

公共类字段

+ + + +

{{Compat("javascript.classes.public_class_fields")}}

+ +

私有类字段

+ + + +

{{Compat("javascript.classes.private_class_fields")}}

+ +

另请参考:

+ + diff --git a/files/zh-cn/web/javascript/reference/classes/constructor/index.html b/files/zh-cn/web/javascript/reference/classes/constructor/index.html new file mode 100644 index 0000000000..334b80e7ad --- /dev/null +++ b/files/zh-cn/web/javascript/reference/classes/constructor/index.html @@ -0,0 +1,132 @@ +--- +title: 构造方法 +slug: Web/JavaScript/Reference/Classes/constructor +tags: + - Classes + - ECMAScript 2015 + - JavaScript +translation_of: Web/JavaScript/Reference/Classes/constructor +--- +
{{jsSidebar("Classes")}}
+ +

 constructor 是一种用于创建和初始化class创建的对象的特殊方法。

+ +

{{EmbedInteractiveExample("pages/js/classes-constructor.html")}}

+ +

语法

+ +
constructor([arguments]) { ... }
+ +

描述

+ +

在一个类中只能有一个名为 “constructor” 的特殊方法。 一个类中出现多次构造函数 (constructor)方法将会抛出一个 {{jsxref("SyntaxError")}} 错误。

+ +

在一个构造方法中可以使用super关键字来调用一个父类的构造方法。

+ +

如果没有显式指定构造方法,则会添加默认的 constructor 方法。

+ +

如果不指定一个构造函数(constructor)方法, 则使用一个默认的构造函数(constructor)。

+ +

示例

+ +

使用constructor方法

+ +

以下代码片段来自 类的实例在线 demo)。

+ +
class Square extends Polygon {
+    constructor(length) {
+        // 在这里, 它调用了父类的构造函数, 并将 lengths 提供给 Polygon 的"width"和"height"
+        super(length, length);
+        // 注意: 在派生类中, 必须先调用 super() 才能使用 "this"。
+        // 忽略这个,将会导致一个引用错误。
+        this.name = 'Square';
+    }
+    get area() {
+        return this.height * this.width;
+    }
+    set area(value) {
+        // 注意:不可使用 this.area = value
+        // 否则会导致循环call setter方法导致爆栈
+        this._area = value;
+    }
+}
+
+
+ +

另一个例子

+ +

看看这个代码片段

+ +
class Polygon {
+    constructor() {
+        this.name = "Polygon";
+    }
+}
+
+class Square extends Polygon {
+    constructor() {
+        super();
+    }
+}
+
+class Rectangle {}
+
+Object.setPrototypeOf(Square.prototype, Rectangle.prototype);
+
+console.log(Object.getPrototypeOf(Square.prototype) === Polygon.prototype); //false
+console.log(Object.getPrototypeOf(Square.prototype) === Rectangle.prototype); //true
+
+let newInstance = new Square();
+console.log(newInstance.name); //Polygon
+
+ +

这里,Square类的原型被改变,但是在正在创建一个新的正方形实例时,仍然调用前一个基类Polygon的构造函数。

+ +

默认构造方法

+ +

如前所述,如果不指定构造方法,则使用默认构造函数。对于基类,默认构造函数是:

+ +
constructor() {}
+ +

对于派生类,默认构造函数是:

+ +
constructor(...args) {
+  super(...args);
+}
+ +

标准

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.classes.constructor")}}

+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/classes/extends/index.html b/files/zh-cn/web/javascript/reference/classes/extends/index.html new file mode 100644 index 0000000000..3166b658fc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/classes/extends/index.html @@ -0,0 +1,106 @@ +--- +title: extends +slug: Web/JavaScript/Reference/Classes/extends +tags: + - Classes + - ECMAScript 2015 + - JavaScript +translation_of: Web/JavaScript/Reference/Classes/extends +--- +
{{jsSidebar("Classes")}}
+ +

extends关键字用于类声明或者类表达式中,以创建一个类,该类是另一个类的子类。

+ +

语法

+ +
class ChildClass extends ParentClass { ... }
+ +

描述

+ +

extends关键字用来创建一个普通类或者内建对象的子类。

+ +

继承的.prototype必须是一个{{jsxref("Object")}} 或者 {{jsxref("null")}}。

+ +

示例

+ +

使用 extends

+ +

第一个例子是根据名为 Polygon 类创建一个名为Square的类。这个例子是从这个在线演示中提取出来的。

+ +
class Square extends Polygon {
+  constructor(length) {
+    // Here, it calls the parent class' constructor with lengths
+    // provided for the Polygon's width and height
+    super(length, length);
+    // Note: In derived classes, super() must be called before you
+    // can use 'this'. Leaving this out will cause a reference error.
+    this.name = 'Square';
+  }
+
+  get area() {
+    return this.height * this.width;
+  }
+}
+ +

使用 extends与内置对象

+ +

这个示例继承了内置的{{jsxref("Date")}}对象。这个例子是从这个在线演示中提取出来的。

+ +
class myDate extends Date {
+  constructor() {
+    super();
+  }
+
+  getFormattedDate() {
+    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
+    return this.getDate() + "-" + months[this.getMonth()] + "-" + this.getFullYear();
+  }
+}
+ +

扩展 null

+ +

可以像扩展普通类一样扩展{{jsxref("null")}},但是新对象的原型将不会继承 {{jsxref("Object.prototype")}}。

+ +
class nullExtends extends null {
+  constructor() {}
+}
+
+Object.getPrototypeOf(nullExtends); // Function.prototype
+Object.getPrototypeOf(nullExtends.prototype) // null
+
+new nullExtends(); //ReferenceError: this is not defined
+ +

标准

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-class-definitions', 'extends')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-class-definitions', 'extends')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.classes.extends")}}

+ +

扩展阅读

+ + diff --git a/files/zh-cn/web/javascript/reference/classes/index.html b/files/zh-cn/web/javascript/reference/classes/index.html new file mode 100644 index 0000000000..f1f7cf7d87 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/classes/index.html @@ -0,0 +1,450 @@ +--- +title: 类 +slug: Web/JavaScript/Reference/Classes +tags: + - ECMAScript 2015 + - Học + - JavaScript + - 中级 + - 构造函数 + - 类 + - 继承 + - 高阶类 +translation_of: Web/JavaScript/Reference/Classes +--- +
+ +
{{JsSidebar("Classes")}}
+ +

类是用于创建对象的模板。他们用代码封装数据以处理该数据。 JS中的类建立在原型上,但也具有某些语法和语义未与ES5类相似语义共享。

+ +

定义类

+ +

实际上,类是“特殊的函数”,就像你能够定义的函数表达式函数声明一样,类语法有两个组成部分:类表达式类声明

+ +

类声明

+ +

定义类的一种方法是使用类声明。要声明一个类,你可以使用带有class关键字的类名(这里是“Rectangle”)。

+ +
class Rectangle {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+}
+ +

提升

+ +

函数声明类声明之间的一个重要区别在于, 函数声明会{{Glossary("Hoisting", "提升")}},类声明不会。你首先需要声明你的类,然后再访问它,否则类似以下的代码将抛出{{jsxref("ReferenceError")}}:

+ +
let p = new Rectangle(); // ReferenceError
+
+class Rectangle {}
+
+ +

类表达式

+ +

类表达式是定义类的另一种方法。类表达式可以命名或不命名。命名类表达式的名称是该类体的局部名称。(不过,可以通过类的(而不是一个实例的) {{jsxref("Function.name", "name")}} 属性来检索它)。

+ +
// 未命名/匿名类
+let Rectangle = class {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+};
+console.log(Rectangle.name);
+// output: "Rectangle"
+
+// 命名类
+let Rectangle = class Rectangle2 {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+};
+console.log(Rectangle.name);
+// 输出: "Rectangle2"
+ +
+

注意: 类表达式也同样受到类声明部分中提到的类型提升的限制。

+
+ +

类体和方法定义

+ +

一个类的类体是一对花括号/大括号 {} 中的部分。这是你定义类成员的位置,如方法或构造函数。

+ +

严格模式

+ +

类声明和类表达式的主体都执行在严格模式下。比如,构造函数,静态方法,原型方法,getter和setter都在严格模式下执行。

+ +

构造函数

+ +

constructor方法是一个特殊的方法,这种方法用于创建和初始化一个由class创建的对象。一个类只能拥有一个名为 “constructor”的特殊方法。如果类包含多个constructor的方法,则将抛出 一个{{jsxref("SyntaxError")}} 。

+ +

一个构造函数可以使用 super 关键字来调用一个父类的构造函数。

+ +

原型方法

+ +

参见方法定义

+ +
class Rectangle {
+    // constructor
+    constructor(height, width) {
+        this.height = height;
+        this.width = width;
+    }
+    // Getter
+    get area() {
+        return this.calcArea()
+    }
+    // Method
+    calcArea() {
+        return this.height * this.width;
+    }
+}
+const square = new Rectangle(10, 10);
+
+console.log(square.area);
+// 100
+
+ +

静态方法

+ +

static 关键字用来定义一个类的一个静态方法。调用静态方法不需要实例化该类,但不能通过一个类实例调用静态方法。静态方法通常用于为一个应用程序创建工具函数。

+ +
class Point {
+    constructor(x, y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    static distance(a, b) {
+        const dx = a.x - b.x;
+        const dy = a.y - b.y;
+        return Math.hypot(dx, dy);
+    }
+}
+
+const p1 = new Point(5, 5);
+const p2 = new Point(10,10);
+p1.displayName;
+// undefined
+p1.distance;
+// undefined
+
+console.log(Point.displayName);
+// "Point"
+console.log(Point.distance(p1, p2));
+// 7.0710678118654755
+
+ +

用原型和静态方法绑定 this

+ +

当调用静态或原型方法时没有指定 this 的值,那么方法内的 this 值将被置为 undefined。即使你未设置 "use strict" ,因为 class 体内部的代码总是在严格模式下执行。

+ +
class Animal {
+  speak() {
+    return this;
+  }
+  static eat() {
+    return this;
+  }
+}
+
+let obj = new Animal();
+obj.speak(); // Animal {}
+let speak = obj.speak;
+speak(); // undefined
+
+Animal.eat() // class Animal
+let eat = Animal.eat;
+eat(); // undefined
+ +

如果上述代码通过传统的基于函数的语法来实现,那么依据初始的 this 值,在非严格模式下方法调用会发生自动装箱。若初始值是 undefinedthis 值会被设为全局对象。

+ +

严格模式下不会发生自动装箱,this 值将保留传入状态。

+ +
function Animal() { }
+
+Animal.prototype.speak = function() {
+  return this;
+}
+
+Animal.eat = function() {
+  return this;
+}
+
+let obj = new Animal();
+let speak = obj.speak;
+speak(); // global object
+
+let eat = Animal.eat;
+eat(); // global object
+
+ +

实例属性

+ +

实例的属性必须定义在类的方法里:

+ +
class Rectangle {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+}
+
+ +

静态的或原型的数据属性必须定义在类定义的外面。

+ +
Rectangle.staticWidth = 20;
+Rectangle.prototype.prototypeWidth = 25;
+
+ +

字段声明

+ +
+

公共和私有字段声明是JavaScript标准委员会TC39提出的实验性功能(第3阶段)。浏览器中的支持是有限的,但是可以通过Babel等系统构建后使用此功能。

+
+ +

公有字段声明

+ +

使用JavaScript字段声明语法,上面的示例可以写成:

+ +
class Rectangle {
+  height = 0;
+  width;
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+}
+
+ +

通过预先声明字段,类定义变得更加自我记录,并且字段始终存在。

+ +

正如上面看到的,这个字段可以用也可以不用默认值来声明。

+ +

私有字段声明

+ +

使用私有字段,可以按以下方式细化定义。

+ +
class Rectangle {
+  #height = 0;
+  #width;
+  constructor(height, width) {
+    this.#height = height;
+    this.#width = width;
+  }
+}
+
+ +

从类外部引用私有字段是错误的。它们只能在类里面中读取或写入。通过定义在类外部不可见的内容,可以确保类的用户不会依赖于内部,因为内部可能在不同版本之间发生变化。

+ +
+

私有字段仅能在字段声明中预先定义。 

+
+ +

私有字段不能通过在之后赋值来创建它们,这种方式只适用普通属性。

+ +

更多信息,请看class fields.

+ +

使用 extends 扩展子类

+ +

extends 关键字在 类声明 或 类表达式 中用于创建一个类作为另一个类的一个子类。

+ +
class Animal {
+  constructor(name) {
+    this.name = name;
+  }
+
+  speak() {
+    console.log(`${this.name} makes a noise.`);
+  }
+}
+
+class Dog extends Animal {
+  constructor(name) {
+    super(name); // 调用超类构造函数并传入name参数
+  }
+
+  speak() {
+    console.log(`${this.name} barks.`);
+  }
+}
+
+var d = new Dog('Mitzie');
+d.speak();// 'Mitzie barks.'
+
+ +

如果子类中定义了构造函数,那么它必须先调用 super() 才能使用 this

+ +

也可以继承传统的基于函数的“类”:

+ +
function Animal (name) {
+  this.name = name;
+}
+Animal.prototype.speak = function () {
+  console.log(this.name + ' makes a noise.');
+}
+
+class Dog extends Animal {
+  speak() {
+    super.speak();
+    console.log(this.name + ' barks.');
+  }
+}
+
+var d = new Dog('Mitzie');
+d.speak();//Mitzie makes a noise.  Mitzie barks.
+ +

请注意,类不能继承常规对象(不可构造的)。如果要继承常规对象,可以改用{{jsxref("Object.setPrototypeOf()")}}:

+ +
var Animal = {
+  speak() {
+    console.log(this.name + ' makes a noise.');
+  }
+};
+
+class Dog {
+  constructor(name) {
+    this.name = name;
+  }
+}
+
+Object.setPrototypeOf(Dog.prototype, Animal);// 如果不这样做,在调用speak时会返回TypeError
+
+var d = new Dog('Mitzie');
+d.speak(); // Mitzie makes a noise.
+ +

Species

+ +

你可能希望在派生数组类 MyArray 中返回 {{jsxref("Array")}}对象。这种 species 方式允许你覆盖默认的构造函数。

+ +

例如,当使用像{{jsxref("Array.map", "map()")}}返回默认构造函数的方法时,您希望这些方法返回一个父Array对象,而不是MyArray对象。{{jsxref("Symbol.species")}} 符号可以让你这样做:

+ +
class MyArray extends Array {
+  // Overwrite species to the parent Array constructor
+  static get [Symbol.species]() { return Array; }
+}
+var a = new MyArray(1,2,3);
+var mapped = a.map(x => x * x);
+
+console.log(mapped instanceof MyArray);
+// false
+console.log(mapped instanceof Array);
+// true
+
+ +

使用 super 调用超类

+ +

super 关键字用于调用对象的父对象上的函数。

+ +
class Cat {
+  constructor(name) {
+    this.name = name;
+  }
+
+  speak() {
+    console.log(this.name + ' makes a noise.');
+  }
+}
+
+class Lion extends Cat {
+  speak() {
+    super.speak();
+    console.log(this.name + ' roars.');
+  }
+}
+
+ +

Mix-ins / 混入

+ +

抽象子类或者 mix-ins 是类的模板。 一个 ECMAScript 类只能有一个单超类,所以想要从工具类来多重继承的行为是不可能的。子类继承的只能是父类提供的功能性。因此,例如,从工具类的多重继承是不可能的。该功能必须由超类提供。

+ +

一个以超类作为输入的函数和一个继承该超类的子类作为输出可以用于在ECMAScript中实现混合:

+ +
var calculatorMixin = Base => class extends Base {
+  calc() { }
+};
+
+var randomizerMixin = Base => class extends Base {
+  randomize() { }
+};
+ +

使用 mix-ins 的类可以像下面这样写:

+ +
class Foo { }
+class Bar extends calculatorMixin(randomizerMixin(Foo)) { }
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ES2016', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2016')}}
{{SpecName('ES2017', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.classes")}}

+ +

重新运行一个类定义

+ +

无法重新定义类。尝试这样做会产生一个 SyntaxError.

+ +

如果您正在使用Web浏览器(例如Firefox Web控制台, (Tools > Web Developer > Web Console)并且您两次“运行”具有相同名称的类的定义,您将收到一个 SyntaxError: redeclaration of let ClassName;. (请参阅中有关此问题的进一步讨论 {{Bug(1428672)}}.) 在Chrome开发者工具中执行类似的操作会给您一个以下信息: Uncaught SyntaxError: Identifier 'ClassName' has already been declared at <anonymous>:1:1.

+ +

参见

+ + + +
+
+
diff --git a/files/zh-cn/web/javascript/reference/classes/private_class_fields/index.html b/files/zh-cn/web/javascript/reference/classes/private_class_fields/index.html new file mode 100644 index 0000000000..a320876884 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/classes/private_class_fields/index.html @@ -0,0 +1,201 @@ +--- +title: 类私有域 +slug: Web/JavaScript/Reference/Classes/Private_class_fields +tags: + - JavaScript + - 类 + - 语言特性 +translation_of: Web/JavaScript/Reference/Classes/Private_class_fields +--- +
{{JsSidebar("Classes")}}
+ +

类属性在默认情况下是公共的,可以被外部类检测或修改。在ES2020 实验草案 中,增加了定义私有类字段的能力,写法是使用一个#作为前缀。

+ +

语法

+ +
class ClassWithPrivateField {
+  #privateField
+}
+
+class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world'
+ }
+}
+
+class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+}
+
+ +

 例子

+ +

私有静态字段

+ +

私有字段可以被类的构造方法(constructor)从内部声明。

+ +

静态变量只能被静态方法调用的限制仍然成立。

+ +
class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+
+  static publicStaticMethod() {
+    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42
+    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD
+  }
+}
+
+assert(ClassWithPrivateStaticField.publicStaticMethod() === 42)
+ +

在类评估时,私有静态字段被添加到类构造函数中。

+ +

私有静态字段有一个来源限制, 只有定义该私有静态字段的类能访问该字段。

+ +

这可能会导致:当使用this时出现意想不到的行为。

+ +
class BaseClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+
+  static basePublicStaticMethod() {
+    this.#PRIVATE_STATIC_FIELD = 42
+    return this.#PRIVATE_STATIC_FIELD
+  }
+}
+
+class SubClass extends BaseClassWithPrivateStaticField { }
+
+assertThrows(() => SubClass.basePublicStaticMethod(), TypeError)
+
+ +

私有实例字段

+ +

私有实例字段使用 #名称(发音为“哈希名称”)声明,这些名称以 #开头。  #是名称本身的一部分, 声明和访问时也需要加上。

+ +

封装由语言强制执行。 从作用域之外引用#名称是语法错误。

+ +
class ClassWithPrivateField {
+  #privateField
+
+  constructor() {
+    this.#privateField = 42
+    this.#randomField = 666 // Syntax error
+  }
+}
+
+const instance = new ClassWithPrivateField()
+instance.#privateField === 42 // Syntax error
+
+ +

私有方法

+ +

私有静态方法

+ +

像它们的公有等价方法一样,私有静态方法是在类本身而非类的实例上调用的。 像私有静态字段一样,只能从类声明内部访问它们。

+ +

私有静态方法可能是生成器方法,异步方法和异步生成器方法。

+ +
class ClassWithPrivateStaticMethod {
+    static #privateStaticMethod() {
+        return 42
+    }
+
+    static publicStaticMethod1() {
+        return ClassWithPrivateStaticMethod.#privateStaticMethod();
+    }
+
+    static publicStaticMethod2() {
+        return this.#privateStaticMethod();
+    }
+}
+
+assert(ClassWithPrivateStaticField.publicStaticMethod1() === 42);
+assert(ClassWithPrivateStaticField.publicStaticMethod2() === 42);
+
+ +

使用this可能会导致意想不到的行为(因为this绑定规则适用)。

+ +
class Base {
+    static #privateStaticMethod() {
+        return 42;
+    }
+    static publicStaticMethod1() {
+        return Base.#privateStaticMethod();
+    }
+    static publicStaticMethod2() {
+        return this.#privateStaticMethod();
+    }
+}
+
+class Derived extends Base {}
+
+console.log(Derived.publicStaticMethod1()); // 42
+console.log(Derived.publicStaticMethod2()); // TypeError
+
+ +

私有实例方法

+ +

私有实例方法是类实例上可用的方法,它们的访问方式与私有实例字段相同。

+ +
class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world'
+  }
+
+  getPrivateMessage() {
+      return this.#privateMethod()
+  }
+}
+
+const instance = new ClassWithPrivateMethod()
+console.log(instance.getPrivateMessage())
+// expected output: "hello worl​d"
+ +

私有实例方法可以是生成器方法,异步方法或异步生成器方法。 私有的getter和setter也是可能的:

+ +
class ClassWithPrivateAccessor {
+  #message
+
+  get #decoratedMessage() {
+    return `✨${this.#message}✨`
+  }
+  set #decoratedMessage(msg) {
+    this.#message = msg
+  }
+
+  constructor() {
+    this.#decoratedMessage = 'hello world'
+    console.log(this.#decoratedMessage)
+  }
+}
+
+new ClassWithPrivateAccessor();
+// expected output: "✨hello worl​d✨"
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('Public and private instance fields', '#prod-FieldDefinition', 'FieldDefinition')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.classes.private_class_fields")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/classes/static/index.html b/files/zh-cn/web/javascript/reference/classes/static/index.html new file mode 100644 index 0000000000..f995fffdbc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/classes/static/index.html @@ -0,0 +1,138 @@ +--- +title: static +slug: Web/JavaScript/Reference/Classes/static +tags: + - Classes + - ECMAScript 2015 + - ES6 + - JavaScript + - Static + - 静态方法 +translation_of: Web/JavaScript/Reference/Classes/static +--- +
{{jsSidebar("Classes")}}
+ +

类(class)通过 static 关键字定义静态方法。不能在类的实例上调用静态方法,而应该通过类本身调用。这些通常是实用程序方法,例如创建或克隆对象的功能。

+ +

 

+ +
{{EmbedInteractiveExample("pages/js/classes-static.html")}}
+ + + +

语法

+ +
static methodName() { ... }
+ +

描述

+ +

静态方法调用直接在类上进行,不能在类的实例上调用。静态方法通常用于创建实用程序函数。

+ +

调用静态方法

+ +

从另一个静态方法

+ +

静态方法调用同一个类中的其他静态方法,可使用 this 关键字。

+ +
class StaticMethodCall {
+    static staticMethod() {
+        return 'Static method has been called';
+    }
+    static anotherStaticMethod() {
+        return this.staticMethod() + ' from another static method';
+    }
+}
+StaticMethodCall.staticMethod();
+// 'Static method has been called'
+
+StaticMethodCall.anotherStaticMethod();
+// 'Static method has been called from another static method'
+
+ +

从类的构造函数和其他方法

+ +

非静态方法中,不能直接使用 this 关键字来访问静态方法。而是要用类名来调用:CLASSNAME.STATIC_METHOD_NAME() ,或者用构造函数的属性来调用该方法: this.constructor.STATIC_METHOD_NAME().

+ +
class StaticMethodCall {
+    constructor() {
+        console.log(StaticMethodCall.staticMethod());
+        // 'static method has been called.'
+        console.log(this.constructor.staticMethod());
+        // 'static method has been called.'
+    }
+    static staticMethod() {
+        return 'static method has been called.';
+    }
+}
+ +

示例

+ +

下面的例子说明了这几点:

+ +
    +
  1. 静态方法如何在类上实现。
  2. +
  3. 具有静态成员的类,可以被子类化 。
  4. +
  5. 什么情况下静态方法可以调用,什么情况下不能调用。
  6. +
+ +

 

+ +
class Tripple {
+  static tripple(n = 1) {
+    return n * 3;
+  }
+}
+
+
+class BiggerTripple extends Tripple {
+  static tripple(n) {
+    return super.tripple(n) * super.tripple(n);
+  }
+}
+
+
+console.log(Tripple.tripple());// 3
+console.log(Tripple.tripple(6));// 18
+
+let tp = new Tripple();
+
+console.log(BiggerTripple.tripple(3));// 81(不会受父类实例化的影响)
+console.log(tp.tripple());// 'tp.tripple 不是一个函数'.
+ +

 

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.classes.static")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/deprecated_and_obsolete_features/index.html b/files/zh-cn/web/javascript/reference/deprecated_and_obsolete_features/index.html new file mode 100644 index 0000000000..3700781397 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/deprecated_and_obsolete_features/index.html @@ -0,0 +1,287 @@ +--- +title: 废弃和过时的特性 +slug: Web/JavaScript/Reference/Deprecated_and_obsolete_features +tags: + - JavaScript + - 废弃 + - 指南 + - 过时 +translation_of: Web/JavaScript/Reference/Deprecated_and_obsolete_features +--- +
{{JsSidebar("More")}}
+ +

本附录列出了那些已经废弃(仍然可用,但是已计划删除)或者过时(已被删除,无法使用)的 JavaScript 特性。

+ +

废弃特性

+ +

这些废弃的特性仍然可以使用,但是使用时一定要保持谨慎,因为它们很可能会在未来的某个时间点被移除。应当将其从需要使用的代码中移除。

+ +

RegExp 对象的属性

+ +

下面的这些属性已经被废弃。注意,这和{{jsxref("String.replace", "替换字符串")}}中使用的同名标记没有直接关系。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性描述
{{jsxref("RegExp.n", "$1-$9")}} +

捕获分组的匹配结果。

+
{{jsxref("RegExp.input", "$_")}}input 属性的别名。
{{jsxref("RegExp.multiline", "$*")}}multiline 属性的别名。
{{jsxref("RegExp.lastMatch", "$&")}}lastMatch 属性的别名。
{{jsxref("RegExp.lastParen", "$+")}}lastParen 属性的别名。
{{jsxref("RegExp.leftContext", "$`")}}leftContext 属性的别名。
{{jsxref("RegExp.rightContext", "$'")}}rightContext 属性的别名。
{{jsxref("RegExp.input", "input")}}正则表达式的匹配结果。
{{jsxref("RegExp.lastMatch", "lastMatch")}}上次匹配结果的最后一个字符串。
{{jsxref("RegExp.lastParen", "lastParen")}}上次匹配中,最后一个捕获分组的匹配结果。
{{jsxref("RegExp.leftContext", "leftContext")}}上次匹配结果左边的字符串。
{{jsxref("RegExp.rightContext", "rightContext")}}上次匹配结果右边的字符串。
+ +

应该使用下面这些 RegExp 实例上的同名属性来代替上面这些 RegExp 对象的属性:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性描述
{{jsxref("RegExp.global", "global")}}该正则是否开启了全局匹配模式。
{{jsxref("RegExp.ignoreCase", "ignoreCase")}}该正则是否开启了忽略大小写模式。
{{jsxref("RegExp.lastIndex", "lastIndex")}}上次成功匹配的索引位置。
{{jsxref("RegExp.multiline", "multiline")}}该正则是否开启了多行模式。
{{jsxref("RegExp.source", "source")}}正则的源文本。
+ +

RegExp 对象的方法

+ +

{{jsxref("RegExp.compile", "compile()")}} 方法已被废弃。

+ +

valueOf 方法已被废弃。使用 {{jsxref("Object.valueOf()")}} 代替它。

+ +

Function 对象的属性

+ +

{{jsxref("Global_Objects/Function/caller", "caller")}} 和 {{jsxref("Global_Objects/Function/arguments", "arguments")}} 属性已经废弃,因为它们会泄漏调用函数的对象。应当在函数内部使用 arguments 对象来代替函数的 arguments 属性。

+ +

遗留的生成器

+ + + +

迭代器

+ + + +

Object 对象的方法

+ + + +

Date 对象的方法

+ + + +

函数

+ + + +

Proxy

+ + + +

转义序列

+ +

字符串字面量(literal)和正则表达式字面量中的八进制转义序列(反斜杠 \ 后跟一到三位的八进制数字)已被废弃。

+ +

{{jsxref("Global_Objects/escape", "escape")}} 函数和 {{jsxref("Global_Objects/unescape", "unescape")}}函数已被废弃。使用 {{jsxref("Global_Objects/encodeURI", "encodeURI")}}、{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}}、{{jsxref("Global_Objects/decodeURI", "decodeURI")}} 或 {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} 对特殊字符进行转义序列编码和解码。

+ +

String 对象的方法

+ + + +

过时特性

+ +

这些过时的特性已经完全被删除,不能在当前或者未来版本的 JavaScript 中使用了。

+ +

Object 对象

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性描述
{{jsxref("Global_Objects/Object/count", "__count__")}}返回用户自定义对象上的可枚举自身属性的个数。
{{jsxref("Global_Objects/Object/Parent", "__parent__")}}指向一个对象的上下文。
{{jsxref("Global_Objects/Object/eval", "Object.prototype.eval()")}}在指定对象的上下文上执行一个包含 JavaScript 代码的字符串。
{{jsxref("Object.observe()")}}Asynchronously observing the changes to an object.
{{jsxref("Object.unobserve()")}}Remove observers.
{{jsxref("Object.getNotifier()")}}Creates an object that allows to synthetically trigger a change.
+ +

函数

+ + + + + + + + + + + + +
属性描述
{{jsxref("Global_Objects/Function/arity", "arity")}}形参的数量。
+ +

Array 对象

+ + + + + + + + + + + + + + + + +
属性描述
{{jsxref("Array.observe()")}}Asynchronously observing changes to Arrays.
{{jsxref("Array.unobserve()")}}Remove observers.
+ +

Number 对象

+ + + +

ParallelArray 对象

+ + + +

声明

+ + + +

E4X

+ +

详见 E4X

+ +

变量引用语法(Sharp variables)

+ +

详见 JavaScript 中的变量引用语法

diff --git a/files/zh-cn/web/javascript/reference/deprecated_and_obsolete_features/the_legacy_iterator_protocol/index.html b/files/zh-cn/web/javascript/reference/deprecated_and_obsolete_features/the_legacy_iterator_protocol/index.html new file mode 100644 index 0000000000..75308950a2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/deprecated_and_obsolete_features/the_legacy_iterator_protocol/index.html @@ -0,0 +1,79 @@ +--- +title: 原始迭代协议 +slug: >- + Web/JavaScript/Reference/Deprecated_and_obsolete_features/The_legacy_Iterator_protocol +tags: + - ES2015 + - JavaScript + - Legacy Iterator + - 传统迭代协议 + - 废弃属性 + - 旧式迭代器 +translation_of: >- + Web/JavaScript/Reference/Deprecated_and_obsolete_features/The_legacy_Iterator_protocol +--- +
{{jsSidebar("More")}}
+ +
非标准。旧式迭代器协议是一个特定于 SpiderMonkey 的功能,在 Firefox 58+ 中删除。对于面向未来的用法,请考虑使用 for..of 循环与迭代协议
+ +

废弃的 Firefox 专用迭代器协议

+ +

Firefox,在版本 26 之前实现了另一个迭代器协议,类似于标准的 ES2015 迭代器协议

+ +

一个对象实现了 next() 方法,并在迭代结束时抛出 {{jsxref("Global_Objects/StopIteration", "StopIteration")}},它就是一个旧式迭代器。

+ + + + + + + + + + + + +
属性
next返回值的零个参数函数。
+ +

旧式迭代器与 ES2015 迭代器的区别

+ + + +

旧迭代器协议示例

+ +
function makeIterator(array){
+    var nextIndex = 0;
+
+    return {
+       next: function(){
+           if(nextIndex < array.length){
+               return array[nextIndex++];
+           else
+               throw new StopIteration();
+       }
+    }
+}
+
+var it = makeIterator(['yo', 'ya']);
+
+console.log(it.next()); // 'yo'
+console.log(it.next()); // 'ya'
+try{
+    console.log(it.next());
+}
+catch(e){
+    if(e instanceof StopIteration){
+         // iteration over
+    }
+}
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/already_has_pragma/index.html b/files/zh-cn/web/javascript/reference/errors/already_has_pragma/index.html new file mode 100644 index 0000000000..28bf001e59 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/already_has_pragma/index.html @@ -0,0 +1,37 @@ +--- +title: 'Warning: -file- is being assigned a //# sourceMappingURL, but already has one' +slug: Web/JavaScript/Reference/Errors/Already_has_pragma +translation_of: Web/JavaScript/Reference/Errors/Already_has_pragma +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
Warning: -file- is being assigned a //# sourceMappingURL, but already has one.
+ +

错误类型

+ +

一个警告。JavaScript 的执行不会中止。

+ +

哪里有问题?

+ +

对于给定的 JavaScript 源码,源码映射规定了不止一次。

+ +

JavaScript 源码通常被组合和压缩,使其从服务器传递更加高效。 使用了源码映射,调试器能够将执行的源码映射到原始的源码。 有两种指派源码映射的方式,通过注释,或者对 JavaScript 设置标题。

+ +

示例

+ +

使用文件中的注释来设置源码映射:

+ +
//# sourceMappingURL=http://example.com/path/to/your/sourcemap.map
+ +

或者,你可以对你的 JavaScript 文件设置一个标题:

+ +
X-SourceMap: /path/to/file.js.map
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/array_sort_argument/index.html b/files/zh-cn/web/javascript/reference/errors/array_sort_argument/index.html new file mode 100644 index 0000000000..1053ea058b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/array_sort_argument/index.html @@ -0,0 +1,47 @@ +--- +title: 'TypeError: invalid Array.prototype.sort argument' +slug: Web/JavaScript/Reference/Errors/Array_sort_argument +tags: + - Errors + - JavaScript + - TypeError +translation_of: Web/JavaScript/Reference/Errors/Array_sort_argument +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
TypeError: invalid Array.prototype.sort argument (Firefox)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

{{jsxref("Array.prototype.sort()")}} 的参数预期为 {{jsxref("undefined")}} 或者是一个比较操作数的函数。

+ +

示例

+ +

无效的

+ +
[1, 3, 2].sort(5);  // TypeError
+
+var cmp = { asc: (x, y) => x >= y, dsc : (x, y) => x <= y };
+[1, 3, 2].sort(cmp[this.key] || 'asc');  // TypeError
+
+ +

有效的

+ +
[1, 3, 2].sort();   // [1, 2, 3]
+
+
+var cmp = { asc: (x, y) => x >= y, dsc : (x, y) => x <= y };
+[1, 3, 2].sort(cmp[this.key || 'asc']); // [1, 2, 3]
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/bad_octal/index.html b/files/zh-cn/web/javascript/reference/errors/bad_octal/index.html new file mode 100644 index 0000000000..2f9b5d477e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/bad_octal/index.html @@ -0,0 +1,55 @@ +--- +title: 'SyntaxError: "x" is not a legal ECMA-262 octal constant' +slug: Web/JavaScript/Reference/Errors/Bad_octal +tags: + - Errors + - JavaScript + - SyntaxError + - 严格模式 +translation_of: Web/JavaScript/Reference/Errors/Bad_octal +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
Warning: SyntaxError: 08 is not a legal ECMA-262 octal constant.
+Warning: SyntaxError: 09 is not a legal ECMA-262 octal constant.
+
+ +

错误类型

+ +

仅在 strict mode 下出现 {{jsxref("SyntaxError")}} 警告。

+ +

哪里出错了?

+ +

十进制字面量可以以零作为开始(0),后面跟着其他十进制数,但是假如前导 0 之后的所有数字都小于 8,那么这个数就会被解析为一个八进制的数。因为 08 和 09 不是这样的,所以 JavaScript 会发出警告。

+ +

请注意,不推荐使用八进制字面值和八进制转义序列,并会产生另外的弃用警告。 在 ECMAScript 6 和更高版本里,语法使用前导零后跟小写或大写拉丁字母“O”(0o或0O)。更多信息请查看 lexical grammar

+ +
+

注意:现在仅 firefox 会产生此错误。

+
+ +

示例

+ +

无效的八进制数

+ +
"use strict";
+08;
+09;
+// SyntaxError: 08 is not a legal ECMA-262 octal constant
+// SyntaxError: octal literals and octal escape sequences are deprecated
+ +

有效的八进制数

+ +

Use a leading zero followed by the letter "o";

+ +
0O755;
+0o644;
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/bad_radix/index.html b/files/zh-cn/web/javascript/reference/errors/bad_radix/index.html new file mode 100644 index 0000000000..1c45f8b6dd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/bad_radix/index.html @@ -0,0 +1,61 @@ +--- +title: 'RangeError: radix must be an integer' +slug: Web/JavaScript/Reference/Errors/Bad_radix +tags: + - JavaScript + - 范围错误 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Bad_radix +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
RangeError: radix must be an integer at least 2 and no greater than 36 (Firefox)
+RangeError: toString() radix argument must be between 2 and 36 (Chrome)
+
+ +

错误类型

+ +

{{jsxref("RangeError")}}

+ +

发生了什么错误?

+ +

在使用{{jsxref("Number.prototype.toString()")}}方法时使用了可选的基数参数,参数应该为一个2到36之间的整型(数字),返回对应数字的转换为字符串时表示的该进制对应的数字量。

+ +

为什么小于36呢?因为一个大于(包含等于)10的基数在使用时需要用一个字母表字符来代替。不能超过36是因为拉丁字母表中只有26个字符。

+ +

你可能会用到以下的常见基数:

+ + + +

示例

+ +

错误示例

+ +
(42).toString(0);
+(42).toString(1);
+(42).toString(37);
+(42).toString(150);
+// You cannot use a string like this for formatting:
+(12071989).toString("MM-dd-yyyy");
+
+ +

正确示例

+ +
(42).toString(2);     // "101010" (binary)
+(13).toString(8);     // "15"     (octal)
+(0x42).toString(10);  // "66"     (decimal)
+(100000).toString(16) // "186a0"  (hexadecimal)
+
+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/bad_regexp_flag/index.html b/files/zh-cn/web/javascript/reference/errors/bad_regexp_flag/index.html new file mode 100644 index 0000000000..6365649479 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/bad_regexp_flag/index.html @@ -0,0 +1,104 @@ +--- +title: 'SyntaxError: invalid regular expression flag "x"' +slug: Web/JavaScript/Reference/Errors/Bad_regexp_flag +tags: + - 语法错误 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Bad_regexp_flag +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
SyntaxError: invalid regular expression flag "x" (Firefox)
+SyntaxError: Invalid regular expression flags (Chrome)
+
+ +

错误类型

+ +

{{jsxref("SyntaxError","语法错误")}}.

+ +

什么地方出错了?

+ +

在代码中出现了无效的正则表达式的标记。在一个正则表达式字面量中,由闭合的两条斜线组成一个模式,(正则表达式的)标记定义在第二个(斜线)标记之后。他们也可以通过{{jsxref("RegExp", "正则表达式")}} 对象的构造函数(第二个参数)来定义。正则表达式的标记可以单独或者任意次序的组合使用,但ECMAScript只规定了五个。

+ +

要使正则表达式包含标记,使用此语法:

+ +
var re = /pattern/flags;
+
+ +

+ +
var re = new RegExp('pattern', 'flags');
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
正则表达式标记
标记说明
g整体检索.
i忽略大小写检索.
m多行检索.
uUnicode; 将模式视为Unicode码点的序列
ysticky 检索将从目标字符串的当前位置开始匹配。参阅{{jsxref("RegExp.sticky", "sticky")}}
+ +

示例

+ +

只有5个有效的正则表达式标记。

+ +
/foo/bar;
+
+// SyntaxError: invalid regular expression flag "b"
+
+ +

你打算创建一个正则表达式吗?一个包含两条斜线的表达式被解释为一个正则表达式的字面量。

+ +
let obj = {
+  url: /docs/Web
+};
+
+// SyntaxError: invalid regular expression flag "W"
+
+ +

还是你想创建一个字符串呢?添加单引号或双引号创建一个字符串字面量。

+ +
let obj = {
+  url: '/docs/Web'
+};
+ +

有效的正则表达式标记

+ +

在JavaScript中允许的五个有效的正则表达式标记,参阅上表。

+ +
/foo/g;
+/foo/gim;
+/foo/uy;
+
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/bad_return_or_yield/index.html b/files/zh-cn/web/javascript/reference/errors/bad_return_or_yield/index.html new file mode 100644 index 0000000000..f2a0fb3de0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/bad_return_or_yield/index.html @@ -0,0 +1,52 @@ +--- +title: 'SyntaxError: return not in function' +slug: Web/JavaScript/Reference/Errors/Bad_return_or_yield +translation_of: Web/JavaScript/Reference/Errors/Bad_return_or_yield +--- +
{{jsSidebar("Errors")}}
+ +

错误信息

+ +
SyntaxError: return not in function
+SyntaxError: yield not in function
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}.

+ +

什么地方出错了?

+ +

return 返回的或者 yield 语句在函数 function 外被调用. 或许是少了一个花括号, return 返回的和 yield 语句必须是在一个函数里,因为它们会停止(暂停或恢复)函数的继续执行,然后返回。

+ +

范例

+ +
var cheer = function(score) {
+  if (score === 147)
+    return "Maximum!";
+  };
+  if (score > 100) {
+    return "Century!";
+  }
+}
+
+// SyntaxError: return not in function
+// 语法错误:不是在函数里返回
+ +

初次看好像没什么错误,但是上面这段代码在第一个 if 后面少了一个 “ { ”。正确的应该如下:

+ +
var cheer = function(score) {
+  if (score === 147) {
+    return "Maximum!";
+  }
+  if (score > 100) {
+    return "Century!";
+  }
+};
+ +

相关信息

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/called_on_incompatible_type/index.html b/files/zh-cn/web/javascript/reference/errors/called_on_incompatible_type/index.html new file mode 100644 index 0000000000..fa6c631c6e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/called_on_incompatible_type/index.html @@ -0,0 +1,63 @@ +--- +title: X.prototype.y called on incompatible type +slug: Web/JavaScript/Reference/Errors/Called_on_incompatible_type +tags: + - JavaScript + - 类型错误 +translation_of: Web/JavaScript/Reference/Errors/Called_on_incompatible_type +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
TypeError: Function.prototype.toString called on incompatible object (Firefox)
+TypeError: Function.prototype.bind called on incompatible target (Firefox)
+TypeError: Method Set.prototype.add called on incompatible receiver undefined (Chrome)
+TypeError: Bind must be called on a function (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

当这个错误被抛出时,属于某个对象的函数被调用,但是没有提供给 this 与其所期望的函数类型一致的参数。

+ +

在调用 {{jsxref("Function.prototype.call()")}} 或{{jsxref("Function.prototype.apply()")}} 方法,但是为 this 提供的绑定对象与预期的不匹配时,这个问题就会出现。

+ +

该问题还会出现于将一个(存储在一个对象中的)函数提供给另外一个函数作为参数时。在这种情况下,函数所在的对象并非该函数的 this  绑定的目标对象。为了解决这个问题,你或者为其提供一个 lambda 表达式,该表达式完成函数要完成的任务,或者调用 {{jsxref("Function.prototype.bind()")}} 函数为 this 强制绑定期望的对象。

+ +

示例

+ +

错误示例

+ +
var mySet = new Set;
+['bar', 'baz'].forEach(mySet.add);
+// mySet.add is a function, but "mySet" is not captured as this.
+
+var myFun = function () {};
+['bar', 'baz'].forEach(myFun.bind);
+// myFun.bind is a function, but "myFun" is not captured as this.
+
+
+ +

正确示例

+ +
var mySet = new Set;
+['bar', 'baz'].forEach(mySet.add.bind(mySet));
+// This works due to binding "mySet" as this.
+
+var myFun = function () {};
+['bar', 'baz'].forEach(x => myFun.bind(x));
+// This works using the "bind" function. It creates a lambda forwarding the argument.
+
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/cant_access_lexical_declaration_before_init/index.html b/files/zh-cn/web/javascript/reference/errors/cant_access_lexical_declaration_before_init/index.html new file mode 100644 index 0000000000..c99aba5c30 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/cant_access_lexical_declaration_before_init/index.html @@ -0,0 +1,56 @@ +--- +title: 'ReferenceError: can''t access lexical declaration`X'' before initialization' +slug: Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init +tags: + - JavaScript + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init +--- +
{{jsSidebar("Errors")}}
+ +

消息提示

+ +
ReferenceError: assignment to undeclared variable "x" (Firefox)
+
+ +

错误类型

+ +

{{jsxref("ReferenceError")}}

+ +

哪里出错了?

+ +

词法变量在初始化之前被访问。该错误可以发生于任何语句块中,当使用 let 或 const 修饰的变量在初始化之前被访问的时候。

+ +

示例

+ +

非法情况

+ +

在这个例子中,变量 "foo" 在语句块中再次声明,导致未初始化。

+ +
function test(){
+   let foo = 33;
+   if (true) {
+      let foo = (foo + 55); // ReferenceError: can't access lexical declaration `foo' before initialization
+   }
+}
+test();
+
+ +

正确情况

+ +

在 if 语句块中修改变量 "foo" 的值,不应该在其中进行二次声明。

+ +
function test(){
+   let foo = 33;
+   if (true) {
+      foo = (foo + 55);
+   }
+}
+test();
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/cant_access_property/index.html b/files/zh-cn/web/javascript/reference/errors/cant_access_property/index.html new file mode 100644 index 0000000000..8f8d830d2c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/cant_access_property/index.html @@ -0,0 +1,55 @@ +--- +title: 'TypeError: can''t access property "x" of "y"' +slug: Web/JavaScript/Reference/Errors/Cant_access_property +translation_of: Web/JavaScript/Reference/Errors/Cant_access_property +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
TypeError: Unable to get property {x} of undefined or null reference (Edge)
+TypeError: can't access property {x} of {y} (Firefox)
+TypeError: {y} is undefined, can't access property {x} of it (Firefox)
+TypeError: {y} is null, can't access property {x} of it (Firefox)
+
+Examples:
+TypeError: x is undefined, can't access property "prop" of it
+TypeError: x is null, can't access property "prop" of it
+TypeError: can't access property "prop" of undefined
+TypeError: can't access property "prop" of null
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}.

+ +

哪里出错了?

+ +

访问了 {{jsxref("undefined")}} 或{{jsxref("null")}} 值的属性.

+ +

例子

+ +

无效情形

+ +
// 对于undefined 以及 null 值, substring 方法无法正常工作
+var foo = undefined;
+foo.substring(1); // TypeError: x is undefined, can't access property "substring" of it
+
+var foo = null;
+foo.substring(1); // TypeError: x is null, can't access property "substring" of it
+
+ +

解决问题

+ +

为了解决undefined 或 null 值的空指针问题,你可以使用 typeof 操作符, 比如.

+ +
if (typeof foo !== 'undefined') {
+  // 现在已经确认foo已定义,可以进一步操作.
+}
+ +

参考更多

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/cant_define_property_object_not_extensible/index.html b/files/zh-cn/web/javascript/reference/errors/cant_define_property_object_not_extensible/index.html new file mode 100644 index 0000000000..6d3d074a8e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/cant_define_property_object_not_extensible/index.html @@ -0,0 +1,66 @@ +--- +title: 'TypeError: can''t define property "x": "obj" is not extensible' +slug: Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible +tags: + - Error + - Errors + - JavaScript + - TypeError + - 类型错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
TypeError: can't define property "x": "obj" is not extensible (Firefox)
+TypeError: Cannot define property: "x", object is not extensible. (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

通常情况下,对象是可以进行扩展的,即可以向其添加新的属性。然而当使用 {{jsxref("Object.preventExtensions()")}} 将一个对象标记为不再可以扩展的情况下,就无法对该对象添加在其被标记为不可扩展之前所拥有的属性之外的新属性了。

+ +

示例

+ +

严格模式下,向已经标记为不可扩展的对象添加新属性会报 TypeError 错误。而在非严格模式下,添加属性 “x” 会被静默忽略。

+ +
'use strict';
+
+var obj = {};
+Object.preventExtensions(obj);
+
+obj.x = 'foo';
+// TypeError: can't define property "x": "obj" is not extensible
+
+ +

严格模式和非严格模式下两种模式下,调用{{jsxref("Object.defineProperty()")}} 向标记为不可扩展的对象添加新属性都会报 TypeError 错误。

+ +
var obj = { };
+Object.preventExtensions(obj);
+
+Object.defineProperty(obj,
+  'x', { value: "foo" }
+);
+// TypeError: can't define property "x": "obj" is not extensible
+
+ +

为了修复这个错误,你可以彻底移除 {{jsxref("Object.preventExtensions()")}} 语句,或者将其移动位置,使得属性在对象被标记为不可扩展之前添加。当然如果不需要试图添加的属性的话,你也可以将其移除。

+ +
'use strict';
+
+var obj = {};
+obj.x = 'foo'; // add property first and only then prevent extensions
+
+Object.preventExtensions(obj);
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/cant_delete/index.html b/files/zh-cn/web/javascript/reference/errors/cant_delete/index.html new file mode 100644 index 0000000000..d92956f409 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/cant_delete/index.html @@ -0,0 +1,58 @@ +--- +title: 'TypeError: property "x" is non-configurable and can''t be deleted' +slug: Web/JavaScript/Reference/Errors/Cant_delete +tags: + - JavaScript + - 严格模式 + - 类型错误 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Cant_delete +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
TypeError: property "x" is non-configurable and can't be deleted. (Firefox)
+TypeError: Cannot delete property 'x' of #<Object> (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}} 只出现在严格模式下。

+ +

哪里有问题?

+ +

尝试删除某个属性,但是这个属性是 不可配置的configurable属性控制是否该属性能从对象上删除,以及它的属性(除了writable)能否被修改。

+ +

这个错误仅仅在严格模式下出现。在非严格模式下,这个操作返回 false

+ +

示例

+ +

不可配置的属性并不特别常见,但是它们可以使用 {{jsxref("Object.defineProperty()")}} 或 {{jsxref("Object.freeze()")}} 创建。

+ +
'use strict';
+var obj = Object.freeze({name: 'Elsa', score: 157});
+delete obj.score;  // TypeError
+
+'use strict';
+var obj = {};
+Object.defineProperty(obj, 'foo', {value: 2, configurable: false});
+delete obj.foo;  // TypeError
+
+'use strict';
+var frozenArray = Object.freeze([0, 1, 2]);
+frozenArray.pop();  // TypeError
+
+ +

也有一些内建于 JavaScript 的不可配置属性。你可能会尝试删除一个数学常量。

+ +
'use strict';
+delete Math.PI;  // TypeError
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/cant_redefine_property/index.html b/files/zh-cn/web/javascript/reference/errors/cant_redefine_property/index.html new file mode 100644 index 0000000000..abba81b6f2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/cant_redefine_property/index.html @@ -0,0 +1,50 @@ +--- +title: 'TypeError: can''t redefine non-configurable property "x"' +slug: Web/JavaScript/Reference/Errors/Cant_redefine_property +tags: + - JavaScript + - 类型错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Cant_redefine_property +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
TypeError: can't redefine non-configurable property "x" (Firefox)
+TypeError: Cannot redefine property: "x" (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

这种错误的起因在于试图给对象重新定义一个属性,但是该属性是不可配置的。 configurable 特性控制着该属性是否可以从对象中删除,以及它的各个特性(除 writable 之外)是否可以修改。通常使用对象初始化语句定义的对象属性是可配置的。而使用 {{jsxref("Object.defineProperty()")}} 定义的属性则默认不可配置。

+ +

示例

+ +

使用 object.defineProperty 创建的不可配置属性

+ +

在使用 {{jsxref("Object.defineProperty()")}} 创建属性的时候,如果没有明确将其设定为可配置的,那么创建出来的属性就是不可配置的。

+ +
var obj = Object.create({});
+Object.defineProperty(obj, "foo", {value: "bar"});
+
+Object.defineProperty(obj, "foo", {value: "baz"});
+// TypeError: can't redefine non-configurable property "foo"
+
+ +

如果想要稍后重新定义的话,那么需要将 "foo" 属性设置为可配置的。

+ +
var obj = Object.create({});
+Object.defineProperty(obj, "foo", {value: "bar", configurable: true});
+Object.defineProperty(obj, "foo", {value: "baz", configurable: true});
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/cyclic_object_value/index.html b/files/zh-cn/web/javascript/reference/errors/cyclic_object_value/index.html new file mode 100644 index 0000000000..9ab3cb7b02 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/cyclic_object_value/index.html @@ -0,0 +1,76 @@ +--- +title: 'TypeError: cyclic object value' +slug: Web/JavaScript/Reference/Errors/Cyclic_object_value +tags: + - Error + - JavaScript + - 类型错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Cyclic_object_value +--- +
{{jsSidebar("Errors")}}
+ +
当一段JSON中出现循环引用,使用{{jsxref("JSON.stringify()")}}这个方法去处理JSON时会报这个"cyclic object value"错误。
+ +

提示信息

+ +
TypeError: cyclic object value (Firefox)
+TypeError: Converting circular structure to JSON (Chrome and Opera)
+TypeError: Circular reference in value argument not supported (Edge)
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

当调用 {{jsxref("JSON.stringify()")}} 方法去处理循环引用结构的JSON会失败。

+ +

JSON标准参考链接:JSON format

+ +

示例

+ +

循环引用

+ +

在如下循环结构中:

+ +
var a = {};
+var b = {};
+a.child = b;
+b.child = a;
+
+ +

{{jsxref("JSON.stringify()")}} 将会报错

+ +
JSON.stringify(a);
+// TypeError: cyclic object value
+
+ +

要处理循环引用的JSON,可以使用支持这种结构的库(例如cycle.js)),或者自己实现。

+ +

下面代码展示了,可以通过指定替换函数({{jsxref("JSON.stringify()")}} 方法的第二个参数) 来检查转换成字符串之前是否有循环对象引用的存在。

+ +

注意:以下代码并不会保存循环引用的值。

+ +
var seen = [];
+
+var replacer = function(key, value) {
+  if (typeof value === "object" && value !== null) {
+    if (seen.indexOf(value) >= 0) {
+      return;
+    }
+    seen.push(value);
+  }
+  return value;
+};
+
+JSON.stringify(a, replacer);
+// "{"child":{}}"
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/dead_object/index.html b/files/zh-cn/web/javascript/reference/errors/dead_object/index.html new file mode 100644 index 0000000000..c974ec27b8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/dead_object/index.html @@ -0,0 +1,49 @@ +--- +title: 'TypeError: can''t access dead object' +slug: Web/JavaScript/Reference/Errors/Dead_object +tags: + - JavaScript + - 插件 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Dead_object +--- +
{{JSSidebar("Errors")}}
+ +

错误提示

+ +
TypeError: can't access dead object
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

为了提高内存使用效率以及防止内存泄露,Firefox 浏览器不允许插件在 DOM 所在的父页面被销毁后对 DOM 对象保持强引用。死对象指的是在 DOM 被销毁后依然持有对 DOM 元素的强引用(处于活跃状态)。为了避免这样的问题,对处于外部文档中的 DOM 节点的引用应该被存储于一个专属于那个文档的对象当中,并且在文档卸载的时候将其清理,或者使用弱引用方式进行存储。

+ +

Checking if an object is dead

+ +

Components.utils offers a isDeadWrapper() method, which privileged code might use.

+ +
if (Components.utils.isDeadWrapper(window)) {
+  // dead
+}
+ +

Unprivileged code has no access to Component.utils and might just be able catch the exception.

+ +
try {
+  String(window);
+}
+catch (e) {
+  console.log("window is likely dead");
+}
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/delete_in_strict_mode/index.html b/files/zh-cn/web/javascript/reference/errors/delete_in_strict_mode/index.html new file mode 100644 index 0000000000..aa9a3293ae --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/delete_in_strict_mode/index.html @@ -0,0 +1,69 @@ +--- +title: >- + SyntaxError: applying the 'delete' operator to an unqualified name is + deprecated +slug: Web/JavaScript/Reference/Errors/Delete_in_strict_mode +tags: + - JavaScript + - 语法错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Delete_in_strict_mode +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: applying the 'delete' operator to an unqualified name is deprecated (Firefox)
+SyntaxError: Delete of an unqualified identifier in strict mode. (Chrome)
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}} 仅出现在严格模式下。

+ +

哪里出错了?

+ +

在 JavaScript 中,普通变量是不能通过 delete 操作符来删除的。在严格模式下,试图去删除一个变量会报错,这是不允许的。

+ +

delete 操作符只能用于删除对象中的属性。只有可配置的对象属性才“符合”被删除的条件。

+ +

与一般流行的观点相反的是, delete 操作符与直接释放内存无关。内存管理是通过切断引用来间接实现的。可以参考内存管理页面与 delete 操作符页面来获取更多的细节信息。

+ +

这个错误提示只出现于严格模式。在非严格模式下,该操作返回 false。

+ +

示例

+ +

在 JavaScript 中,普通变量是不能删除的,在严格模式下会报错:

+ +
'use strict';
+
+var x;
+
+// ...
+
+delete x;
+
+// SyntaxError: applying the 'delete' operator to an unqualified name
+// is deprecated
+
+ +

要释放变量引用的内容,可以将变量值设置为 {{jsxref("null")}}:

+ +
'use strict';
+
+var x;
+
+// ...
+
+x = null;
+
+// x can be garbage collected
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/deprecated_caller_or_arguments_usage/index.html b/files/zh-cn/web/javascript/reference/errors/deprecated_caller_or_arguments_usage/index.html new file mode 100644 index 0000000000..cfafd9c155 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/deprecated_caller_or_arguments_usage/index.html @@ -0,0 +1,76 @@ +--- +title: 'ReferenceError: deprecated caller or arguments usage' +slug: Web/JavaScript/Reference/Errors/Deprecated_caller_or_arguments_usage +tags: + - Errors + - JavaScript + - Strict Mode + - 严格模式 + - 警告 +translation_of: Web/JavaScript/Reference/Errors/Deprecated_caller_or_arguments_usage +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
Warning: ReferenceError: deprecated caller usage (Firefox)
+Warning: ReferenceError: deprecated arguments usage (Firefox)
+TypeError: 'callee' and 'caller' cannot be accessed in strict mode. (Safari)
+
+ +

错误类型

+ +

仅在严格模式下出现的 {{jsxref("ReferenceError")}} 警告。JavaScript 的执行将不会停止。

+ +

发生了什么?

+ +

strict mode 中,{{jsxref("Function.caller")}} 和 {{jsxref("Function.arguments")}} 属性是不该使用的。它们都是已经被废弃的了,因为这两者泄露了函数的调用者,是不标准的,难于优化和有这潜在的性能问题。

+ +

实力

+ +

废弃的 function.caller or arguments.callee.caller

+ +

{{jsxref("Function.caller")}} 和 arguments.callee.caller 都是已废弃的 (详见参考文章)。

+ +
"use strict";
+
+function myFunc() {
+  if (myFunc.caller == null) {
+    return 'The function was called from the top!';
+  } else {
+    return 'This function\'s caller was ' + myFunc.caller;
+  }
+}
+
+myFunc();
+// Warning: ReferenceError: deprecated caller usage
+// "The function was called from the top!"
+ +

Function.arguments

+ +

{{jsxref("Function.arguments")}} 已被废弃。 (详见参考文章)。

+ +
"use strict";
+
+function f(n) { g(n - 1); }
+
+function g(n) {
+  console.log('before: ' + g.arguments[0]);
+  if (n > 0) { f(n); }
+  console.log('after: ' + g.arguments[0]);
+}
+
+f(2);
+
+console.log('returned: ' + g.arguments);
+// Warning: ReferenceError: deprecated arguments usage
+
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/deprecated_expression_closures/index.html b/files/zh-cn/web/javascript/reference/errors/deprecated_expression_closures/index.html new file mode 100644 index 0000000000..465bd6741b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/deprecated_expression_closures/index.html @@ -0,0 +1,78 @@ +--- +title: 'Warning: expression closures are deprecated' +slug: Web/JavaScript/Reference/Errors/Deprecated_expression_closures +tags: + - JavaScript + - 警告 +translation_of: Web/JavaScript/Reference/Errors/Deprecated_expression_closures +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
Warning: expression closures are deprecated
+
+ +

错误类型

+ +

警告。JavaScript 引擎不会停止运行。

+ +

哪里出错了?

+ +

非标准化的表达式闭包语法(简写函数语法)已被废弃,不应该再被使用。该语法将会在 {{bug(1083458)}} 中全部移除,到时候用到该语法的脚本程序会报  SyntaxError 错误。

+ +

示例

+ +

被废弃的语法

+ +

表达式闭包从函数声明或者对象方法定义中省略了花括号或是 return 语句。

+ +
var x = function() 1;
+
+var obj = {
+  count: function() 1
+};
+
+ +

标准语法

+ +

将非标准化的表达式闭包语法转换成标准 ECMAScript 语法,可以添加花括号以及 return 语句。

+ +
var x = function() { return 1; }
+
+var obj = {
+  count: function() { return 1; }
+};
+
+ +

标准语法之箭头函数

+ +

另外,你可以选择使用箭头函数:

+ +
var x = () => 1;
+ +

标准语法之方法的简略写法

+ +

表达式闭包还会出现在 getter 与 setter 中,例如:

+ +
var obj = {
+  get x() 1,
+  set x(v) this.v = v
+};
+
+ +

根据 ES2015 中对于方法定义的规定,上述写法可以转换成如下形式:

+ +
var obj = {
+  get x() { return 1 },
+  set x(v) { this.v = v }
+};
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/deprecated_octal/index.html b/files/zh-cn/web/javascript/reference/errors/deprecated_octal/index.html new file mode 100644 index 0000000000..ca56bc00ac --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/deprecated_octal/index.html @@ -0,0 +1,67 @@ +--- +title: 'SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated' +slug: Web/JavaScript/Reference/Errors/Deprecated_octal +tags: + - JavaScript + - 严格模式 + - 语法错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Deprecated_octal +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError:
+"0"-prefixed octal literals and octal escape sequences are deprecated;
+for octal literals use the \"0o\" prefix instead
+
+ +

错误类型

+ +

语法错误({{jsxref("SyntaxError")}} ),只出现于严格模式下。

+ +

哪里出错了?

+ +

八进制字面量与八进制转义序列语法已经被废弃,在严格模式下会报语法错误({{jsxref("SyntaxError")}})。在 ECMAScript 2015 及以后的规范中,标准语法是前导 0 后面跟一个大写或小写的拉丁文字母 "O" (0o 或 0O)。

+ +

示例

+ +

前导"0"形式的八进制字面量

+ +
"use strict";
+
+03;
+
+// SyntaxError: "0"-prefixed octal literals and octal escape sequences
+// are deprecated
+ +

八进制转义序列

+ +
"use strict";
+
+"\251";
+
+// SyntaxError: "0"-prefixed octal literals and octal escape sequences
+// are deprecated
+
+ +

合法的八进制数字

+ +

使用前导 0 后面跟字母 "o" 或 "O" 的形式:

+ +
0o3;
+
+ +

至于八进制转义序列,你可以使用十六进制转义序列来代替:

+ +
'\xA9';
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/deprecated_source_map_pragma/index.html b/files/zh-cn/web/javascript/reference/errors/deprecated_source_map_pragma/index.html new file mode 100644 index 0000000000..e37aec2fa3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/deprecated_source_map_pragma/index.html @@ -0,0 +1,109 @@ +--- +title: >- + SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# + instead +slug: Web/JavaScript/Reference/Errors/Deprecated_source_map_pragma +tags: + - Errors + - JavaScript + - Source maps +translation_of: Web/JavaScript/Reference/Errors/Deprecated_source_map_pragma +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
Warning: SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead
+
+Warning: SyntaxError: Using //@ to indicate sourceMappingURL pragmas is deprecated. Use //# instead
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}} 的警告。不会终止 JavaScript 的执行。

+ +

哪里错了?

+ +

在 JavaScript 源码中使用了已废弃的 source map 语法。

+ +

JavaScript 源代码经常被组合和压缩,以便能更高效地从服务器获取它们。使用了 source maps,调试器就可以将正在执行的代码映射到原始源文件。

+ +

因为 IE 浏览器只要页面在 //@cc_on 之后的都会被IE JScript引擎解释为打开条件编译后,所以 source map 的规范更改了语法。条件编译注释 是 IE 的一个小特色,但是它破坏了 jQuery 和其他库的 source map。

+ +

示例

+ +

废弃的语法

+ +

使用 "@" 符号的语法已经被废弃了。

+ +
//@ sourceMappingURL=http://example.com/path/to/your/sourcemap.map
+
+ +

标准语法

+ +

使用 "#" 符号代替。

+ +
//# sourceMappingURL=http://example.com/path/to/your/sourcemap.map
+ +

或者,您也可以为 JavaScript 文件设置 header,以避免添加注释:

+ +
X-SourceMap: /path/to/file.js.map
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
New syntax{{CompatVersionUnknown}}{{ CompatGeckoDesktop(24) }}{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
New syntax{{CompatUnknown}}{{CompatUnknown}}{{ CompatGeckoMobile(24) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/deprecated_string_generics/index.html b/files/zh-cn/web/javascript/reference/errors/deprecated_string_generics/index.html new file mode 100644 index 0000000000..dd59c26276 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/deprecated_string_generics/index.html @@ -0,0 +1,104 @@ +--- +title: 'Warning: String.x is deprecated; use String.prototype.x instead' +slug: Web/JavaScript/Reference/Errors/Deprecated_String_generics +tags: + - JavaScript + - 警告 +translation_of: Web/JavaScript/Reference/Errors/Deprecated_String_generics +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
Warning: String.charAt            is deprecated; use String.prototype.charAt            instead
+Warning: String.charCodeAt        is deprecated; use String.prototype.charCodeAt        instead
+Warning: String.concat            is deprecated; use String.prototype.concat            instead
+Warning: String.contains          is deprecated; use String.prototype.contains          instead
+Warning: String.endsWith          is deprecated; use String.prototype.endsWith          instead
+Warning: String.includes          is deprecated; use String.prototype.includes          instead
+Warning: String.indexOf           is deprecated; use String.prototype.indexOf           instead
+Warning: String.lastIndexOf       is deprecated; use String.prototype.lastIndexOf       instead
+Warning: String.localeCompare     is deprecated; use String.prototype.localeCompare     instead
+Warning: String.match             is deprecated; use String.prototype.match             instead
+Warning: String.normalize         is deprecated; use String.prototype.normalize         instead
+Warning: String.replace           is deprecated; use String.prototype.replace           instead
+Warning: String.search            is deprecated; use String.prototype.search            instead
+Warning: String.slice             is deprecated; use String.prototype.slice             instead
+Warning: String.split             is deprecated; use String.prototype.split             instead
+Warning: String.startsWith        is deprecated; use String.prototype.startsWith        instead
+Warning: String.substr            is deprecated; use String.prototype.substr            instead
+Warning: String.substring         is deprecated; use String.prototype.substring         instead
+Warning: String.toLocaleLowerCase is deprecated; use String.prototype.toLocaleLowerCase instead
+Warning: String.toLocaleUpperCase is deprecated; use String.prototype.toLocaleUpperCase instead
+Warning: String.toLowerCase       is deprecated; use String.prototype.toLowerCase       instead
+Warning: String.toUpperCase       is deprecated; use String.prototype.toUpperCase       instead
+Warning: String.trim              is deprecated; use String.prototype.trim              instead
+Warning: String.trimLeft          is deprecated; use String.prototype.trimLeft          instead
+Warning: String.trimRight         is deprecated; use String.prototype.trimRight         instead
+
+ +

错误类型

+ +

警告。JavaScript 引擎不会停止运行。

+ +

哪里出错了?

+ +

非标准的泛型  {{jsxref("String")}} 方法已经被废弃,将来会被移除(这些方法仅在 Firefox 浏览器中得到实现)。String 泛型在 String 对象上提供了一系列的 String 实例方法,使得这些 String 方法可以应用于任何类型的对象。

+ +

Firefox {{bug(1222552)}} 对 String 泛型方法的移除进行了追踪。

+ +

示例

+ +

废弃的语法

+ +
var num = 15;
+String.replace(num, /5/, '2');
+ +

标准语法

+ +
var num = 15;
+String(num).replace(/5/, '2');
+
+ +

垫片

+ +

以下是一个垫片脚本来为不支持 String 泛型方法浏览器提供支持:

+ +
/*globals define*/
+// Assumes all supplied String instance methods already present
+// (one may use shims for these if not available)
+(function() {
+  'use strict';
+
+  var i,
+    // We could also build the array of methods with the following, but the
+    //   getOwnPropertyNames() method is non-shimable:
+    // Object.getOwnPropertyNames(String).filter(function(methodName) {
+    //   return typeof String[methodName] === 'function';
+    // });
+    methods = [
+      'contains', 'substring', 'toLowerCase', 'toUpperCase', 'charAt',
+      'charCodeAt', 'indexOf', 'lastIndexOf', 'startsWith', 'endsWith',
+      'trim', 'trimLeft', 'trimRight', 'toLocaleLowerCase', 'normalize',
+      'toLocaleUpperCase', 'localeCompare', 'match', 'search', 'slice',
+      'replace', 'split', 'substr', 'concat', 'localeCompare'
+    ],
+    methodCount = methods.length,
+    assignStringGeneric = function(methodName) {
+      var method = String.prototype[methodName];
+      String[methodName] = function(arg1) {
+        return method.apply(arg1, Array.prototype.slice.call(arguments, 1));
+      };
+    };
+
+  for (i = 0; i < methodCount; i++) {
+    assignStringGeneric(methods[i]);
+  }
+}());
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/deprecated_tolocaleformat/index.html b/files/zh-cn/web/javascript/reference/errors/deprecated_tolocaleformat/index.html new file mode 100644 index 0000000000..e8e8040227 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/deprecated_tolocaleformat/index.html @@ -0,0 +1,90 @@ +--- +title: 'Warning: Date.prototype.toLocaleFormat is deprecated' +slug: Web/JavaScript/Reference/Errors/Deprecated_toLocaleFormat +tags: + - JavaScript + - 警告 +translation_of: Web/JavaScript/Reference/Errors/Deprecated_toLocaleFormat +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
Warning: Date.prototype.toLocaleFormat is deprecated; consider using Intl.DateTimeFormat instead
+
+ +

错误类型

+ +

警告。JavaScript 引擎不会停止运行。

+ +

哪里出错了?

+ +

{{jsxref("Date.prototype.toLocaleFormat")}} 是非标准化的方法,已经被废弃,不应该再进行使用。该方法需要传入与 C 语言中的strftime() 方法相似的格式化字符串。该实现将会在 {{bug(818634)}} 中完全移除。

+ +

示例

+ +

废止使用的语法

+ +

{{jsxref("Date.prototype.toLocaleFormat")}} 方法已经废弃,以后会被移除(只在 Firefox 浏览器中有用到,没有在其他浏览器中使用)。

+ +
var today = new Date();
+var date = today.toLocaleFormat('%A, %e. %B %Y');
+
+console.log(date);
+// In German locale
+// "Freitag, 10. März 2017"
+ +

备选标准语法之一:使用 ECMAScript Intl API 

+ +

ECMA-402 (ECMAScript Intl API) 标准规定了支持不同语言的日期和时间格式化形式的对象和方法(在 Chrome 24+, Firefox 29+, IE11+, Safari10+ 中可用)。

+ +

现在如果只需要格式化一个日期对象的话,那么可以使用 {{jsxref("Date.prototype.toLocaleDateString")}} 方法。

+ +
var today = new Date();
+var options = { weekday: 'long', year: 'numeric',
+                month: 'long', day: 'numeric' };
+var date = today.toLocaleDateString('de-DE', options);
+
+console.log(date);
+// "Freitag, 10. März 2017"
+
+ +

或者,可以使用 {{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}} 对象,该对象允许你将格式化器对象缓存起来,省去很多重复性的计算工作,所以格式化操作会很快。这在需要对一系列的日期对象进行格式化的时候非常有用。

+ +
var options = { weekday: 'long', year: 'numeric',
+                month: 'long', day: 'numeric' };
+var dateFormatter = new Intl.DateTimeFormat('de-DE', options)
+
+var dates = [Date.UTC(2012, 11, 20, 3, 0, 0),
+             Date.UTC(2014, 04, 12, 8, 0, 0)];
+
+dates.forEach(date => console.log(dateFormatter.format(date)));
+
+// "Donnerstag, 20. Dezember 2012"
+// "Montag, 12. Mai 2014"
+
+ +

备选标准语法之二:使用 Date 对象的方法

+ +

{{jsxref("Date")}} 对象提供了一系列的方法来生成定制化的格式化字符串。

+ +
(new Date()).toLocaleFormat("%Y%m%d");
+// "20170310"
+
+ +

可以转换为:

+ +
let now = new Date();
+let date = now.getFullYear() * 10000 +
+          (now.getMonth() + 1) * 100 + now.getDate();
+
+console.log(date);
+// "20170310"
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/equal_as_assign/index.html b/files/zh-cn/web/javascript/reference/errors/equal_as_assign/index.html new file mode 100644 index 0000000000..e92f0a63e8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/equal_as_assign/index.html @@ -0,0 +1,52 @@ +--- +title: 'SyntaxError: test for equality (==) mistyped as assignment (=)?' +slug: Web/JavaScript/Reference/Errors/Equal_as_assign +tags: + - 语法错误 +translation_of: Web/JavaScript/Reference/Errors/Equal_as_assign +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
Warning: SyntaxError: test for equality (==) mistyped as assignment (=)?
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}} 只在严格模式下会出现的警告。

+ +

什么地方出错了?

+ +

在通常期望进行相等判定(==)的地方出现了赋值(=)。 为了帮助调试,JavaScript(在开启严格模式的情况下)会对这种情况进行警告。

+ +

示例

+ +

条件表达式内的赋值

+ +

不建议在条件表达式中 (例如 if...else) 使用简单赋值语句,因为在扫视代码的时候赋值操作与相等判定容易产生混淆。例如,不要使用以下写法:

+ +
if (x = y) {
+  // do the right thing
+}
+
+ +

如果你需要在条件表达式中使用赋值语句, 通常的做法是用一对括号把赋值语句包起来。 例如:

+ +
if ((x = y)) {
+  // do the right thing
+}
+ +

否则, 你的本意可能是想用比较操作符 (如 =====):

+ +
if (x == y) {
+  // do the right thing
+}
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/for-each-in_loops_are_deprecated/index.html b/files/zh-cn/web/javascript/reference/errors/for-each-in_loops_are_deprecated/index.html new file mode 100644 index 0000000000..351be47a9d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/for-each-in_loops_are_deprecated/index.html @@ -0,0 +1,171 @@ +--- +title: 'Warning: JavaScript 1.6''s for-each-in loops are deprecated' +slug: Web/JavaScript/Reference/Errors/For-each-in_loops_are_deprecated +tags: + - Warning +translation_of: Web/JavaScript/Reference/Errors/For-each-in_loops_are_deprecated +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
警告: JavaScript 1.6's 版本的for-each-in遍历不再赞成使用; 建议用 ES6的 for-of 替换
+
+ +

错误类型

+ +

警告

+ +

出了什么问题?

+ +

JavaScript 1.6's {{jsxref("Statements/for_each...in", "for each (variable in obj)")}}语法不赞成使用, 将在未来版本移除它。

+ +

实例

+ +

遍历对象

+ +

{{jsxref("Statements/for_each...in", "for each...in")}} 用来遍历指定对象.

+ +

不赞成这么使用

+ +
+

var object = { a: 10, b: 20 };

+ +

for each (var x in object) {
+   console.log(x);        // 10
+                          // 20
+ }

+
+ +

替换语法

+ +

你可以使用 {{jsxref("Statements/for...in", "for...in")}} 遍历指定对象, 获取每次循环的值:

+ +
var object = { a: 10, b: 20 };
+
+for (var key in object) {
+  var x = object[key];
+  console.log(x);        // 10
+                         // 20
+}
+
+ +

也可以使用{jsxref("Statements/for...of", "for...of")}} (ES2015) 和 {{jsxref("Object.values")}} (ES2017), 你可以获取指定对象的值得数组然后像这样遍历它:

+ +
var object = { a: 10, b: 20 };
+
+for (var x of Object.values(object)) {
+  console.log(x);        // 10
+                         // 20
+}
+
+ +

数组遍历

+ +

{{jsxref("Statements/for_each...in", "for each...in")}} 被用于遍历制定数组.

+ +

不赞成这么使用

+ +
+

var array = [10, 20, 30];

+ +

for each (var x in array) {
+   console.log(x);        // 10
+                          // 20
+                          // 30
+ }

+
+ +

替换语法

+ +

现在最好用{{jsxref("Statements/for...of", "for...of")}} (ES2015) 替换

+ +
var array = [10, 20, 30];
+
+for (var x of array) {
+  console.log(x);        // 10
+                         // 20
+                         // 30
+}
+
+ +

遍历一个空数组

+ +

{{jsxref("Statements/for_each...in", "for each...in")}} 如果指定值是 null o或 undefined什么都遍历不出来。 {{jsxref("Statements/for...of", "for...of")}} 在这种情况会抛出异常.

+ +

不赞成这么使用

+ +
+

function func(array) {
+   for each (var x in array) {
+     console.log(x);
+   }
+ }
+ func([10, 20]);        // 10
+                        // 20
+ func(null);            // prints nothing
+ func(undefined);       // prints nothing

+
+ +

替换语法

+ +

用{{jsxref("Statements/for...of", "for...of")}} 重写{{jsxref("Statements/for_each...in", "for each...in")}} 后值可以为 null 和 undefined  ,同时你需要警惕{{jsxref("Statements/for...of", "for...of")}}抛出的异常.

+ +
function func(array) {
+  if (array) {
+    for (var x of array) {
+      console.log(x);
+    }
+  }
+}
+func([10, 20]);        // 10
+                       // 20
+func(null);            // prints nothing
+func(undefined);       // prints nothing
+
+ +

遍历对象键值对

+ +

不赞成这么使用

+ +

 不赞成使用{{jsxref("Statements/for_each...in", "for each...in")}}和{{jsxref("Iterator")}} 对象来遍历指定对象的键值对.

+ +
+

var object = { a: 10, b: 20 };

+ +

for each (var [key, value] in Iterator(object)) {
+   console.log(key, value);  // "a", 10
+                             // "b", 20
+ }

+
+ +

替换语法

+ +

你可以使用 {{jsxref("Statements/for...in", "for...in")}} 遍历指定对象,获取每次循环的值:

+ +
var object = { a: 10, b: 20 };
+
+for (var key in object) {
+  var value = object[key];
+  console.log(key, value);  // "a", 10
+                            // "b", 20
+}
+
+ +

也可以使用{jsxref("Statements/for...of", "for...of")}} (ES2015) 和 {{jsxref("Object.values")}} (ES2017), 你可以获取指定对象的值得数组然后像这样遍历它:

+ +
var object = { a: 10, b: 20 };
+
+for (var [key, value] of Object.entries(object)) {
+  console.log(key, value);  // "a", 10
+                            // "b", 20
+}
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/getter_only/index.html b/files/zh-cn/web/javascript/reference/errors/getter_only/index.html new file mode 100644 index 0000000000..0636f30eea --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/getter_only/index.html @@ -0,0 +1,82 @@ +--- +title: 'TypeError: setting getter-only property "x"' +slug: Web/JavaScript/Reference/Errors/Getter_only +tags: + - JavaScript + - 严格模式 + - 类型错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Getter_only +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
TypeError: setting getter-only property "x" (Firefox)
+TypeError: Cannot set property "prop" of #<Object> which has only a getter (Chrome)
+
+ +

错误类型

+ +

仅在严格模式下报 {{jsxref("TypeError")}} 错误。

+ +

哪里出错了?

+ +

该错误提示出现于试图给一个仅仅设置了 getter 特性的属性赋新值的时候。在非严格模式下会被静默忽略,而在严格模式下会报 {{jsxref("TypeError")}} 错误。

+ +

示例

+ +

下面的例子展示了如何为一个属性设置 getter 特性。由于没有设置 setter 特性,所以在试图将 temperature 属性值设置为 30 的时候会报 TypeError 的错误。相关细节信息可以参考 {{jsxref("Object.defineProperty()")}} 页面。

+ +
"use strict";
+
+function Archiver() {
+  var temperature = null;
+  Object.defineProperty(this, 'temperature', {
+    get: function() {
+      console.log('get!');
+      return temperature;
+    }
+  });
+}
+
+var arc = new Archiver();
+arc.temperature; // 'get!'
+
+arc.temperature = 30;
+// TypeError: setting getter-only property "temperature"
+ +

至于修复问题的方法,可以将第 16 行的代码移除,因为它试图为 temperature 属性赋值,或者是为它添加一个 setter 特性,就像下面这样:

+ +
"use strict";
+
+function Archiver() {
+  var temperature = null;
+  var archive = [];
+
+  Object.defineProperty(this, 'temperature', {
+    get: function() {
+      console.log('get!');
+      return temperature;
+    },
+    set: function(value) {
+      temperature = value;
+      archive.push({ val: temperature });
+    }
+  });
+
+  this.getArchive = function() { return archive; };
+}
+
+var arc = new Archiver();
+arc.temperature; // 'get!'
+arc.temperature = 11;
+arc.temperature = 13;
+arc.getArchive(); // [{ val: 11 }, { val: 13 }]
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/identifier_after_number/index.html b/files/zh-cn/web/javascript/reference/errors/identifier_after_number/index.html new file mode 100644 index 0000000000..c2607edd2b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/identifier_after_number/index.html @@ -0,0 +1,48 @@ +--- +title: 'SyntaxError: identifier starts immediately after numeric literal' +slug: Web/JavaScript/Reference/Errors/Identifier_after_number +translation_of: Web/JavaScript/Reference/Errors/Identifier_after_number +--- +
{{JSSidebar("Errors")}}
+ +

Message

+ +
SyntaxError: identifier starts immediately after numeric literal (Firefox)
+SyntaxError: Unexpected number (Chrome)
+
+ +

Error type

+ +

{{jsxref("SyntaxError")}}

+ +

What went wrong?

+ +

变量名叫{{Glossary("Identifier", "identifiers")}},它符合某些规则,而你打破了这些规则!

+ +

一个JavaScript标识符必须以字母开头,下划线(_)或美元符号($)。他们不能以数字开头。只有后续字符可以是数字(0-9)。

+ +

Examples

+ +

Variable names starting with numeric literals

+ +

Variable names can't start with numbers in JavaScript. The following fails:

+ +
var 1life = 'foo';
+// SyntaxError: identifier starts immediately after numeric literal
+
+var foo = 1life;
+// SyntaxError: identifier starts immediately after numeric literal
+
+ +

You will need to rename your variable to avoid the leading number.

+ +
var life1 = 'foo';
+var foo = life1;
+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/illegal_character/index.html b/files/zh-cn/web/javascript/reference/errors/illegal_character/index.html new file mode 100644 index 0000000000..16367c43a2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/illegal_character/index.html @@ -0,0 +1,73 @@ +--- +title: 'SyntaxError: illegal character' +slug: Web/JavaScript/Reference/Errors/Illegal_character +tags: + - JavaScript + - 语法错误 +translation_of: Web/JavaScript/Reference/Errors/Illegal_character +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: illegal character (Firefox)
+SyntaxError: Invalid or unexpected token (Chrome)
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

在代码中有非法的或者不期望出现的标记符号出现在不该出现的位置。请使用支持语法高亮功能的编辑器仔细检查你的代码,看看是否存在张冠李戴的情况,比如减号 ( - ) 与连接符 () ,或者是英文双引号 ( " ) 与中文双引号 ()。

+ +

示例

+ +

错配字符

+ +

一些字符看起来会很相像,但是会导致于语法解析器解析代码失败。

+ +
“This looks like a string”;
+// SyntaxError: illegal character
+
+42 – 13;
+// SyntaxError: illegal character
+
+ +

下面这样是可以正常运行的:

+ +
"This is actually a string";
+
+42 - 13;
+
+ +

遗漏的字符

+ +

很容易就会在这里或那里遗漏一些字符。

+ +
var colors = ['#000', #333', '#666'];
+// SyntaxError: illegal character
+
+ +

把遗漏的引号给 '#333' 添加上。

+ +
var colors = ['#000', '#333', '#666'];
+ +

隐藏字符

+ +

当从外部复制粘贴代码的时候,有可能就有非法的隐藏字符的存在,需要引起注意!

+ +
var foo = 'bar';​
+// SyntaxError: illegal character
+
+ +

当使用文本编辑器如VIM进行探测的时候,可以发现这里存在一个零宽空格 (ZWSP) (U+200B) 。

+ +
var foo = 'bar';​<200b>
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/in_operator_no_object/index.html b/files/zh-cn/web/javascript/reference/errors/in_operator_no_object/index.html new file mode 100644 index 0000000000..fa607780a7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/in_operator_no_object/index.html @@ -0,0 +1,71 @@ +--- +title: 'TypeError: invalid ''in'' operand "x"' +slug: Web/JavaScript/Reference/Errors/in_operator_no_object +tags: + - JavaScript + - 类型错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/in_operator_no_object +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
TypeError: invalid 'in' operand "x" (Firefox)
+TypeError: Cannot use 'in' operator to search for 'x' in y (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

in 操作符只可以用来检测对象中是否存在某个属性,而不能用来在字符串、数字或者其他基本类型的数据中进行检索。

+ +

示例

+ +

在字符串中进行检索

+ +

与其他语言不同(如 Python),不能使用 in 操作符在字符串中进行检索。

+ +
"Hello" in "Hello World";
+// TypeError: invalid 'in' operand "Hello World"
+
+ +

可以使用 {{jsxref("String.prototype.indexOf()")}} 来代替:

+ +
"Hello World".indexOf("Hello") !== -1;
+// true
+ +

操作数不能为 null 或者 undefined

+ +

确保你将要进行探测的对象不为 {{jsxref("null")}} 或者  {{jsxref("undefined")}}.

+ +
var foo = null;
+"bar" in foo;
+// TypeError: invalid 'in' operand "foo"
+
+ +

in 操作符的预期操作数只有对象类型。

+ +
var foo = { baz: "bar" };
+"bar" in foo; // false
+
+"PI" in Math; // true
+"pi" in Math; // false
+
+ +

在数组中进行检索

+ +

当使用 in 操作符来对 {{jsxref("Array")}} 对象进行检索的时候一定要特别小心,因为它检测的是索引值而不是位于索引位置的值。

+ +
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
+3 in trees; // true
+"oak" in trees; // false
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/index.html b/files/zh-cn/web/javascript/reference/errors/index.html new file mode 100644 index 0000000000..f0c0f2560a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/index.html @@ -0,0 +1,28 @@ +--- +title: JavaScript 错误参考 +slug: Web/JavaScript/Reference/Errors +tags: + - Debugging + - Errors + - JavaScript + - 调试 + - 错误 +translation_of: Web/JavaScript/Reference/Errors +--- +

{{jsSidebar("Errors")}}

+ +

下面列出了 JavaScript 抛出的错误。这些错误是有用的调试帮助,但报告的问题并不总是十分明了。下面的页面提供有关这些错误的详细信息。每个错误都是基于 {{jsxref("Error")}}  的对象,并且具有名称和消息。

+ +

Web 控制台中显示的错误可能包含指向下面相应页面的链接,以帮助您快速理解代码中的问题。

+ +

错误列表

+ +

在此列表中,每个页面按名称(错误类型)和信息(更详细的容易理解的错误信息)列出。 总之,这两者提供了理解和解决错误的线索。 有关更多信息,请按照以下链接!

+ +

{{ListSubPages("/zh-CN/docs/Web/JavaScript/Reference/Errors")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/invalid_array_length/index.html b/files/zh-cn/web/javascript/reference/errors/invalid_array_length/index.html new file mode 100644 index 0000000000..6e74db20b8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/invalid_array_length/index.html @@ -0,0 +1,77 @@ +--- +title: 'RangeError: invalid array length' +slug: Web/JavaScript/Reference/Errors/Invalid_array_length +tags: + - JavaScript + - 范围错误 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Invalid_array_length +--- +
{{jsSidebar("Errors")}}
+ +

错误信息

+ +
RangeError: invalid array length (Firefox)
+RangeError: Invalid array length (Chrome)
+RangeError: Invalid array buffer length (Chrome)
+
+ +

错误类型

+ +

{{jsxref("RangeError")}}

+ +

什么地方出错了?

+ +

无效的数组错误长度通常会在以下情形中出现:

+ + + +

为什么 Array(数组) 和 ArrayBuffer(数组缓冲区) 的长度会受到限制?因为 Array 和 ArrayBuffer 的 length(长度) 属性被定义为一个32位无符号整形(unsigned 32-bit integer)的值,所以它只能存储 0 - 232-1 之间的数。

+ +

当你使用构造函数来创建一个数组的时候,你可能想使用字面值的形式,第一个参数会被解释为数组的长度。

+ +

或者说,你想要在设置数组之前确定它的长度,或把它作为一个构造函数的参数。

+ +

示例

+ +

错误的示例

+ +
new Array(Math.pow(2, 40))
+new Array(-1)
+new ArrayBuffer(Math.pow(2, 32))
+new ArrayBuffer(-1)
+
+let a = [];
+a.length = a.length - 1;         // 将 length 属性的值设置为 -1
+
+let b = new Array(Math.pow(2, 32) - 1);
+b.length = b.length + 1;         // 将 length 属性的值设置为 2^32
+
+ +

正确的示例

+ +
[ Math.pow(2, 40) ]                     // [ 1099511627776 ]
+[ -1 ]                                  // [ -1 ]
+new ArrayBuffer(Math.pow(2, 32) - 1)
+new ArrayBuffer(0)
+
+let a = [];
+a.length = Math.max(0, a.length - 1);
+
+let b = new Array(Math.pow(2, 32) - 1);
+b.length = Math.min(0xffffffff, b.length + 1);
+
+// 0xffffffff 是 2^32 - 1 的 十六进制 表示方式
+// 它也可以被写作 (-1 >>> 0)
+
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/invalid_assignment_left-hand_side/index.html b/files/zh-cn/web/javascript/reference/errors/invalid_assignment_left-hand_side/index.html new file mode 100644 index 0000000000..e3506fc199 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/invalid_assignment_left-hand_side/index.html @@ -0,0 +1,54 @@ +--- +title: 'ReferenceError: invalid assignment left-hand side' +slug: Web/JavaScript/Reference/Errors/Invalid_assignment_left-hand_side +tags: + - Errors + - JavaScript + - ReferenceError +translation_of: Web/JavaScript/Reference/Errors/Invalid_assignment_left-hand_side +--- +
{{jsSidebar("Errors")}}
+ +

Message

+ +
ReferenceError: invalid assignment left-hand side
+
+ +

Error type

+ +

{{jsxref("ReferenceError")}}.

+ +

What went wrong?

+ +

有时会出现不可预料的赋值情况。这可能是因为赋值运算符比较运算符不匹配的缘故。正确的是,使用“=”号将值赋给一个变量,使用“==”或者“===”来比较一个值。

+ +

Examples

+ +
if (Math.PI = 3 || Math.PI = 4) {
+  console.log('no way!');
+}
+// ReferenceError: invalid assignment left-hand side
+
+var str = 'Hello, '
++= 'is it me '
++= 'you\'re looking for?';
+// ReferenceError: invalid assignment left-hand side
+
+ +

if 语句中,你要使用比较运算符("=="),而在字符串连接中,使用加号运算符("+")。

+ +
if (Math.PI == 3 || Math.PI == 4) {
+  console.log('no way!');
+}
+
+var str = 'Hello, '
++ 'from the '
++ 'other side!';
+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/invalid_const_assignment/index.html b/files/zh-cn/web/javascript/reference/errors/invalid_const_assignment/index.html new file mode 100644 index 0000000000..330bab78c8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/invalid_const_assignment/index.html @@ -0,0 +1,90 @@ +--- +title: 'TypeError: invalid assignment to const "x"' +slug: Web/JavaScript/Reference/Errors/Invalid_const_assignment +tags: + - JavaScript + - 类型错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Invalid_const_assignment +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
TypeError: invalid assignment to const "x" (Firefox)
+TypeError: Assignment to constant variable. (Chrome)
+TypeError: Redeclaration of const 'x' (IE/Edge)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

常量指的是无法在程序正常运行过程中进行修改的值。一方面无法通过重新赋值进行修改,另外一方面也无法进行重新声明。在 JavaScript 中,常量通过关键字 const 来声明。

+ +

示例

+ +

不合法的二次声明

+ +

在同一作用域内为相同的常量名进行赋值会报错。

+ +
const COLUMNS = 80;
+
+// ...
+
+COLUMNS = 120; // TypeError: invalid assignment to const `COLUMNS'
+ +

问题修复

+ +

修复的方式有很多种。可以根据你想要达到的目的来有针对性地对其进行处理。

+ +

重新命名

+ +

如果想要声明另一个变量,那么请选择其他名称对其重新命名。原来的常量名在该作用域中已经被占有。

+ +
const COLUMNS = 80;
+const WIDE_COLUMNS = 120;
+ +

const, let or var?

+ +

如果你的目的不是为了创建一个常量的话,那么就不要使用 const 关键字。可以使用 let 关键字来声明一个拥有块作用域的变量,或者使用 var 来声明一个全局变量。

+ +
let columns = 80;
+
+// ...
+
+let columns = 120;
+
+ +

作用域

+ +

检查一下作用域是否正确。例如这个常量是否应该出现在当前作用域,还是应该出现在函数内部?

+ +
const COLUMNS = 80;
+
+function setupBigScreenEnvironment() {
+  const COLUMNS = 120;
+}
+ +

const与不可变性

+ +

const 声明语句创建了一个对值的只读引用。这并意味着它指向的值是不可变的,而是说这个变量标记符不能被再次分配。例如,在值是对象的情况下,引用的对象自身内容依然是可以改变的。不能改变该变量的引用:

+ +
const obj = {foo: 'bar'};
+obj = {foo: 'baz'}; // TypeError: invalid assignment to const `obj'
+
+ +

但是可以改变它引用的值的属性: 

+ +
obj.foo = 'baz';
+obj; // Object { foo: "baz" }
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/invalid_date/index.html b/files/zh-cn/web/javascript/reference/errors/invalid_date/index.html new file mode 100644 index 0000000000..1deee46fcc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/invalid_date/index.html @@ -0,0 +1,54 @@ +--- +title: 'RangeError: invalid date' +slug: Web/JavaScript/Reference/Errors/Invalid_date +tags: + - JavaScript + - 范围错误 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Invalid_date +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
范围错误: 非法数据(Firefox)
+范围错误: 非法时间值 (Chrome)
+范围错误: 提供的数据不是有效的 (Chrome)
+
+ +

错误类型

+ +

{{jsxref("RangeError")}}

+ +

哪里出错了?

+ +

为 {{jsxref("Date")}} 或 {{jsxref("Date.parse()")}} 提供了一个会导致无效日期的字符串。

+ +

示例

+ +

错误示例

+ +

ISO格式化字符串中不可识别的字符串或者包含非法元素值的日期一般会返回 {{jsxref("NaN")}}。然而,根据实现的不同,不符合ISO格式的字符串可能也会抛出 RangeError: invalid date,比如在火狐浏览器中有以下情形:

+ +
new Date('foo-bar 2014');
+new Date('2014-25-23').toISOString();
+new Date('foo-bar 2014').toString();
+
+ +

然而下面这种情形会返回 {{jsxref("NaN")}} :

+ +
Date.parse('foo-bar 2014'); // NaN
+ +

参见 {{jsxref("Date.parse()")}} 文档,了解更多详情。

+ +

正确示例

+ +
new Date('05 October 2011 14:48 UTC');
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/invalid_for-in_initializer/index.html b/files/zh-cn/web/javascript/reference/errors/invalid_for-in_initializer/index.html new file mode 100644 index 0000000000..34dcefa8ed --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/invalid_for-in_initializer/index.html @@ -0,0 +1,73 @@ +--- +title: 'SyntaxError: for-in loop head declarations may not have initializers' +slug: Web/JavaScript/Reference/Errors/Invalid_for-in_initializer +tags: + - JavaScript + - 严格模式 + - 语法错误 +translation_of: Web/JavaScript/Reference/Errors/Invalid_for-in_initializer +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: for-in loop head declarations may not have initializers (Firefox)
+
+SyntaxError: for-in loop variable declaration may not have an initializer. (Chrome)
+
+ +

错误类型

+ +

该 {{jsxref("SyntaxError")}} 只出现于严格模式下。

+ +

哪里出错了?

+ +

在 for...in 循环的头部存在初始化表达式。 也就是存在变量声明并且被赋值,例如 |for (var i = 0 in obj)|。在非严格模式下,这种在循环头部的变量声明会被静默忽略,语句的表现形式与 |for (var i in obj)|相同。而在严格模式下,会报语法错误。

+ +

示例

+ +

下面这个示例会报语法错误(SyntaxError):

+ +
"use strict";
+
+var obj = {a: 1, b: 2, c: 3 };
+
+for (var i = 0 in obj) {
+  console.log(obj[i]);
+}
+
+// SyntaxError: for-in loop head declarations may not have initializers
+
+ +

合法的 for-in 循环

+ +

可以把初始化语句 (i = 0) 从 for-in 循环的头部移除。

+ +
"use strict";
+
+var obj = {a: 1, b: 2, c: 3 };
+
+for (var i in obj) {
+  console.log(obj[i]);
+}
+
+ +

数组迭代

+ +

for...in 循环不应该应用于数组迭代中。是否考虑使用 for 循环而不是 for-in 循环来遍历数组({{jsxref("Array")}})?在 for 循环中是允许使用初始化语句的:

+ +
var arr = [ "a", "b", "c" ]
+
+for (var i = 2; i < arr.length; i++) {
+  console.log(arr[i]);
+}
+
+// "c"
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/invalid_for-of_initializer/index.html b/files/zh-cn/web/javascript/reference/errors/invalid_for-of_initializer/index.html new file mode 100644 index 0000000000..7e93d3af35 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/invalid_for-of_initializer/index.html @@ -0,0 +1,63 @@ +--- +title: >- + SyntaxError: a declaration in the head of a for-of loop can't have an + initializer +slug: Web/JavaScript/Reference/Errors/Invalid_for-of_initializer +tags: + - JavaScript + - 语法错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Invalid_for-of_initializer +--- +
{{jsSidebar("Errors")}}
+ +

错误信息

+ +
SyntaxError: a declaration in the head of a for-of loop can't have an initializer (Firefox)
+
+SyntaxError: for-of loop variable declaration may not have an initializer. (Chrome)
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

for...of 循环的头部包含有初始化表达式。也就是对一个变量进行声明并赋值|for (var i = 0 of iterable)|。这在 for-of 循环中是被禁止的。你想要的可能是允许包含初始化器的 for 循环形式。

+ +

示例

+ +

非法的 for-of 循环形式

+ +
let iterable = [10, 20, 30];
+
+for (let value = 50 of iterable) {
+  console.log(value);
+}
+
+// SyntaxError: a declaration in the head of a for-of loop can't
+// have an initializer
+ +

合法的 for-of 循环形式

+ +

需要将初始化器 (value = 50) 从for-of 循环的头部移除。或许你的本意是给每个值添加 50 的偏移量,在这种情况下,可以在循环体中进行添加。

+ +
let iterable = [10, 20, 30];
+
+for (let value of iterable) {
+  value += 50;
+  console.log(value);
+}
+// 60
+// 70
+// 80
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/invalid_right_hand_side_instanceof_operand/index.html b/files/zh-cn/web/javascript/reference/errors/invalid_right_hand_side_instanceof_operand/index.html new file mode 100644 index 0000000000..2ce2214034 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/invalid_right_hand_side_instanceof_operand/index.html @@ -0,0 +1,56 @@ +--- +title: 'TypeError: invalid ''instanceof'' operand ''x''' +slug: Web/JavaScript/Reference/Errors/invalid_right_hand_side_instanceof_operand +translation_of: Web/JavaScript/Reference/Errors/invalid_right_hand_side_instanceof_operand +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
TypeError: invalid 'instanceof' operand "x" (Firefox)
+TypeError: "x" is not a function (Firefox)
+TypeError: Right-hand side of 'instanceof' is not an object (Chrome)
+TypeError: Right-hand side of 'instanceof' is not callable (Chrome)
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

instanceof 操作符 希望右边的操作数为一个构造对象,即一个有 prototype 属性且可以调用的对象。

+ +

例子

+ +
"test" instanceof ""; // TypeError: invalid 'instanceof' operand ""
+42 instanceof 0;      // TypeError: invalid 'instanceof' operand 0
+
+function Foo() {}
+var f = Foo();        // Foo() is called and returns undefined
+var x = new Foo();
+
+x instanceof f;       // TypeError: invalid 'instanceof' operand f
+x instanceof x;       // TypeError: x is not a function
+
+ +

为了解决上述问题, 你可能需要将instanceof 操作符 换成 typeof 操作符, 或者确保你使用的是函数名称,而不是函数计算的结果。

+ +
typeof "test" == "string"; // true
+typeof 42 == "number"      // true
+
+function Foo() {}
+var f = Foo;               // Do not call Foo.
+var x = new Foo();
+
+x instanceof f;            // true
+x instanceof Foo;          // true
+
+ +

参见

+ + + +

 

diff --git a/files/zh-cn/web/javascript/reference/errors/is_not_iterable/index.html b/files/zh-cn/web/javascript/reference/errors/is_not_iterable/index.html new file mode 100644 index 0000000000..a3cd34eb82 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/is_not_iterable/index.html @@ -0,0 +1,126 @@ +--- +title: 'TypeError: ''x'' is not iterable' +slug: Web/JavaScript/Reference/Errors/is_not_iterable +tags: + - 生成器 + - 迭代器 +translation_of: Web/JavaScript/Reference/Errors/is_not_iterable +--- +
{{jsSidebar("Errors")}}
+ +

错误信息

+ +
TypeError: 'x' is not iterable (Firefox, Chrome)
+TypeError: 'x' is not a function or its return value is not iterable (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

发生了什么错误?

+ +

这个值作为 for…of  的表达式右值,或者作为一个函数的参数,如 {{jsxref("Promise.all")}} 或者 {{jsxref("TypedArray.from")}}, 不是一个 可迭代对象.  一个可迭代对象可以是一个内置可迭代类型,如{{jsxref("Array")}}, {{jsxref("String")}} 或 {{jsxref("Map")}}, 一个 generator 生成结果, 或者一个实现了 可迭代协议 的对象

+ +

示例

+ +

Iterating over Object properties

+ +

在JavaScript中, {{jsxref("Object")}} 是不可迭代的,除非它们实现了迭代协议. 因此, 你不能使用 for…of 来迭代对象的属性.

+ +
var obj = { 'France': 'Paris', 'England': 'London' };
+for (let p of obj) { // TypeError: obj is not iterable
+    // …
+}
+
+ +

做为替代你必须使用 {{jsxref("Object.keys")}} 或 {{jsxref("Object.entries")}} 来迭代对象的属性或属性值.

+ +
var obj = { 'France': 'Paris', 'England': 'London' };
+// 迭代属性名称:
+for (let country of Object.keys(obj)) {
+    var capital = obj[country];
+    console.log(country, capital);
+}
+
+for (const [country, capital] of Object.entries(obj))
+    console.log(country, capital);
+
+ +

这次case的另外一个选择是使用 {{jsxref("Map")}}:

+ +
var map = new Map;
+map.set('France', 'Paris');
+map.set('England', 'London');
+// Iterate over the property names:
+for (let country of map.keys()) {
+    let capital = map[country];
+    console.log(country, capital);
+}
+
+for (let capital of map.values())
+    console.log(capital);
+
+for (const [country, capital] of map.entries())
+    console.log(country, capital);
+
+ +

Iterating over a generator

+ +

Generators 是用来生成可迭代对象的函数.

+ +
function* generate(a, b) {
+  yield a;
+  yield b;
+}
+
+for (let x of generate) // TypeError: generate is not iterable
+    console.log(x);
+
+ +

当它没有被调用, 这个 {{jsxref("Function")}} 相应的是可调用的,但是不可迭代。 调用 generator 生成一个可迭代对象,该对象将迭代在生成器执行期间生成的值.

+ +
function* generate(a, b) {
+    yield a;
+    yield b;
+}
+
+for (let x of generate(1,2))
+    console.log(x);
+ +

Iterating over a custom iterable

+ +

可以使用{{jsxref("Symbol.iterator")}} 方法去实现一个自定义迭代器。你必须确定自定义的迭代器方法返回一个迭代器对象,即它必须有一个next()

+ +
const myEmptyIterable = {
+    [Symbol.iterator]() {
+        return [] // [] is iterable, but it is not an iterator -- it has no next method.
+    }
+}
+
+Array.from(myEmptyIterable);  // TypeError: myEmptyIterable is not iterable
+
+ +

+
+

下面是正确用法

+ +
const myEmptyIterable = {
+    [Symbol.iterator]() {
+        return [][Symbol.iterator]()
+    }
+}
+
+Array.from(myEmptyIterable);  // []
+
+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/json_bad_parse/index.html b/files/zh-cn/web/javascript/reference/errors/json_bad_parse/index.html new file mode 100644 index 0000000000..cac9176d80 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/json_bad_parse/index.html @@ -0,0 +1,111 @@ +--- +title: 'SyntaxError: JSON.parse: bad parsing' +slug: Web/JavaScript/Reference/Errors/JSON_bad_parse +tags: + - Errors + - JSON + - JavaScript + - SyntaxError + - 方法 +translation_of: Web/JavaScript/Reference/Errors/JSON_bad_parse +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
SyntaxError: JSON.parse: unterminated string literal
+SyntaxError: JSON.parse: bad control character in string literal
+SyntaxError: JSON.parse: bad character in string literal
+SyntaxError: JSON.parse: bad Unicode escape
+SyntaxError: JSON.parse: bad escape character
+SyntaxError: JSON.parse: unterminated string
+SyntaxError: JSON.parse: no number after minus sign
+SyntaxError: JSON.parse: unexpected non-digit
+SyntaxError: JSON.parse: missing digits after decimal point
+SyntaxError: JSON.parse: unterminated fractional number
+SyntaxError: JSON.parse: missing digits after exponent indicator
+SyntaxError: JSON.parse: missing digits after exponent sign
+SyntaxError: JSON.parse: exponent part is missing a number
+SyntaxError: JSON.parse: unexpected end of data
+SyntaxError: JSON.parse: unexpected keyword
+SyntaxError: JSON.parse: unexpected character
+SyntaxError: JSON.parse: end of data while reading object contents
+SyntaxError: JSON.parse: expected property name or '}'
+SyntaxError: JSON.parse: end of data when ',' or ']' was expected
+SyntaxError: JSON.parse: expected ',' or ']' after array element
+SyntaxError: JSON.parse: end of data when property name was expected
+SyntaxError: JSON.parse: expected double-quoted property name
+SyntaxError: JSON.parse: end of data after property name when ':' was expected
+SyntaxError: JSON.parse: expected ':' after property name in object
+SyntaxError: JSON.parse: end of data after property value in object
+SyntaxError: JSON.parse: expected ',' or '}' after property value in object
+SyntaxError: JSON.parse: expected ',' or '}' after property-value pair in object literal
+SyntaxError: JSON.parse: property names must be double-quoted strings
+SyntaxError: JSON.parse: expected property name or '}'
+SyntaxError: JSON.parse: unexpected character
+SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

{{jsxref("JSON.parse()")}} 会把一个字符串解析成 JSON 对象。如果字符串书写正确,那么其将会被解析成一个有效的 JSON,但是这个字符串被检测出错误语法的时候将会抛出错误。

+ +

示例

+ +

JSON.parse() 不允许在末尾添加多余的逗号

+ +

下面两行代码都会抛出错误:

+ +
JSON.parse('[1, 2, 3, 4, ]');
+JSON.parse('{"foo" : 1, }');
+// SyntaxError JSON.parse: unexpected character
+// at line 1 column 14 of the JSON data
+
+ +

省略末尾多余的逗号解析 JSON 就是正确:

+ +
JSON.parse('[1, 2, 3, 4 ]');
+JSON.parse('{"foo" : 1 }');
+ +

JSON 的属性名必须使用双引号

+ +

属性名上不能使用单引号,例如: 'foo'。

+ +
JSON.parse("{'foo' : 1 }");
+// SyntaxError: JSON.parse: expected property name or '}'
+// at line 1 column 2 of the JSON data
+ +

取而代之,写成 "foo":

+ +
JSON.parse('{"foo" : 1 }');
+ +

前导 0 和小数点

+ +

数字不能用 0 开头,比如01,并且你的小数点后面必须跟着至少一个数字。

+ +
JSON.parse('{"foo" : 01 }');
+// SyntaxError: JSON.parse: expected ',' or '}' after property value
+// in object at line 1 column 2 of the JSON data
+
+JSON.parse('{"foo" : 1. }');
+// SyntaxError: JSON.parse: unterminated fractional number
+// at line 1 column 2 of the JSON data
+
+ +

正确的写法应该是只写一个1,不书写前面的0。在小数点的后面至少要跟上一个数字:

+ +
JSON.parse('{"foo" : 1 }');
+JSON.parse('{"foo" : 1.0 }');
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/malformed_formal_parameter/index.html b/files/zh-cn/web/javascript/reference/errors/malformed_formal_parameter/index.html new file mode 100644 index 0000000000..edbee71c60 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/malformed_formal_parameter/index.html @@ -0,0 +1,61 @@ +--- +title: 'SyntaxError: Malformed formal parameter' +slug: Web/JavaScript/Reference/Errors/Malformed_formal_parameter +tags: + - Errors + - JavaScript + - SyntaxError +translation_of: Web/JavaScript/Reference/Errors/Malformed_formal_parameter +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
SyntaxError: malformed formal parameter (Firefox)
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里错了?

+ +

在至少带有两个参数的 Function() 构造器中它的最后一个参数是创建的新函数的源代码。剩下的都是新函数的参数。

+ +

构造器的参数有些情况下是无效的。 也许是你不小心用了一个关键字 if 或 var 作为参数名称,或者在参数列表中有一些杂乱的标点符号。 或者也许你不小心传递了一个无效的值,比如数字或对象。

+ +

好吧,这解决了我的问题。但是为什么不开始就说明白呢?

+ +

诚然,错误信息中的措辞稍微有些奇怪。"Formal parameter" 是 "function argument" 的另一种优美的同义。 我们使用 “malformed”(即畸形)这个词,因为所有的Firefox工程师都是19世纪哥特式恐怖小说的巨星。

+ +

示例

+ +

无效的

+ +
var f = Function("x y", "return x + y;");
+// SyntaxError (missing a comma)
+
+var f = Function("x,", "return x;");
+// SyntaxError (extraneous comma)
+
+var f = Function(37, "alert('OK')");
+// SyntaxError (numbers can't be argument names)
+
+ +

有效的

+ +
var f = Function("x, y", "return x + y;");  // correctly punctuated
+
+var f = Function("x", "return x;");
+
+// if you can, avoid using Function - this is much faster
+var f = function (x) { return x; };
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/malformed_uri/index.html b/files/zh-cn/web/javascript/reference/errors/malformed_uri/index.html new file mode 100644 index 0000000000..40bb10ae1d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/malformed_uri/index.html @@ -0,0 +1,65 @@ +--- +title: 'URIError: malformed URI sequence' +slug: Web/JavaScript/Reference/Errors/Malformed_URI +tags: + - JavaScript + - URLError + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Malformed_URI +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
URIError: malformed URI sequence (Firefox)
+URIError: URI malformed (Chrome)
+
+ +

错误类型

+ +

{{jsxref("URIError")}}

+ +

哪里出错了?

+ +

URI 编码和解码不成功。传递给 {{jsxref("decodeURI")}}、{{jsxref("encodeURI")}}、{{jsxref("encodeURIComponent")}} 或者 {{jsxref("decodeURIComponent")}} 这些函数的参数不合法,导致函数无法正确对其进行编解码。

+ +

示例

+ +

编码

+ +

编码操作会将每一个字符实例替换为一到四个相对应的 UTF-8 编码形式的转义序列。如果试图编码一个非高-低位完整的代理字符,将会抛出一个 {{jsxref("URIError")}} 错误,例如:

+ +
encodeURI('\uD800');
+// "URIError: malformed URI sequence"
+
+encodeURI('\uDFFF');
+// "URIError: malformed URI sequence"
+
+ +

高-低位完整的代理字符是没问题的,例如:

+ +
encodeURI('\uD800\uDFFF');
+// "%F0%90%8F%BF"
+ +

解码

+ +

解码操作则是将已经经过编码的 URL 片段中的每一个转义序列替换为相对应的字符。如果相应的字符不存在,就会抛出错误:

+ +
decodeURIComponent('%E0%A4%A');
+// "URIError: malformed URI sequence"
+
+ +

输入没问题的话,通常是下面这样:

+ +
decodeURIComponent('JavaScript_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B');
+// "JavaScript_шеллы"
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_bracket_after_list/index.html b/files/zh-cn/web/javascript/reference/errors/missing_bracket_after_list/index.html new file mode 100644 index 0000000000..d1da610184 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_bracket_after_list/index.html @@ -0,0 +1,56 @@ +--- +title: 'SyntaxError: missing ] after element list' +slug: Web/JavaScript/Reference/Errors/Missing_bracket_after_list +tags: + - Errors + - JavaScript + - SyntaxError +translation_of: Web/JavaScript/Reference/Errors/Missing_bracket_after_list +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
SyntaxError: missing ] after element list
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}.

+ +

哪里出错了?

+ +

数组初始化在某处出现了语法错误。比如缺少了右中括号("]") 或一个逗号 (",")。

+ +

示例

+ +

不正确的数组初始化

+ +
var list = [1, 2,
+
+var instruments = [
+  "Ukulele",
+  "Guitar",
+  "Piano"
+};
+
+var data = [{foo: "bar"} {bar: "foo"}];
+
+ +

正确的是:

+ +
var list = [1, 2];
+
+var instruments = [
+ "Ukulele",
+ "Guitar",
+ "Piano"
+];
+
+var data = [{foo: "bar"}, {bar: "foo"}];
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_colon_after_property_id/index.html b/files/zh-cn/web/javascript/reference/errors/missing_colon_after_property_id/index.html new file mode 100644 index 0000000000..7cfdf7e318 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_colon_after_property_id/index.html @@ -0,0 +1,76 @@ +--- +title: 'SyntaxError: missing : after property id' +slug: Web/JavaScript/Reference/Errors/Missing_colon_after_property_id +tags: + - JavaScript + - 语法错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Missing_colon_after_property_id +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: missing : after property id
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

当使用对象初始化语法创建对象的时候,需要使用半角冒号 (:) 将属性键与属性值隔开。

+ +
var obj = { propertyKey: 'value' };
+
+ +

示例

+ +

冒号与等号

+ +

下面的代码会运行失败,原因是对象初始化语法中不允许使用等号来代替冒号。

+ +
var obj = { propertyKey = 'value' };
+// SyntaxError: missing : after property id
+
+ +

修复方法就是使用冒号,或者是在对象创建之后使用方括号语法来为其设定新的属性。

+ +
var obj = { propertyKey: 'value' };
+
+// or alternatively
+
+var obj = { };
+obj['propertyKey'] = 'value';
+
+ +

空属性

+ +

不能像下面这样创建空属性:

+ +
var obj = { propertyKey; };
+// SyntaxError: missing : after property id
+
+ +

假如你需要创建一个无值属性,那么需要将它的值设置为 {{jsxref("null")}} 。

+ +
var obj = { propertyKey: null };
+ +

计算得来的属性

+ +

如果需要使用表达式来创建属性键,那么需要使用方括号。否则属性名称不会进行计算:

+ +
var obj = { 'b'+'ar': 'foo' };
+// SyntaxError: missing : after property id
+
+ +

把计算表达式放置到方括号([])中:

+ +
var obj = { ['b'+'ar']: 'foo' };
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_curly_after_function_body/index.html b/files/zh-cn/web/javascript/reference/errors/missing_curly_after_function_body/index.html new file mode 100644 index 0000000000..36761114d1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_curly_after_function_body/index.html @@ -0,0 +1,66 @@ +--- +title: 'SyntaxError: missing } after function body' +slug: Web/JavaScript/Reference/Errors/Missing_curly_after_function_body +tags: + - JavaScript + - 语法错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Missing_curly_after_function_body +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: missing } after function body
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

在创建函数的时候出现了语法错误。检查一下闭合花括号以及括号的顺序是否正确。将代码进行缩进或者美化可以让你更容易找到问题之所在。

+ +

示例

+ +

遗漏的闭合花括号

+ +

通常是因为在函数声明中遗漏了花括号:

+ +
var charge = function() {
+  if (sunny) {
+    useSolarCells();
+  } else {
+    promptBikeRide();
+};
+
+ +

正确的应该是这样的:

+ +
var charge = function() {
+  if (sunny) {
+    useSolarCells();
+  } else {
+    promptBikeRide();
+  }
+};
+ +

当使用立即调用函数表达式({{Glossary("IIFE")}})、闭包或者其他使用了大量的花括号以及括号的结构体的时候,问题会更加隐蔽。

+ +
(function() { if (true) { return false; } );
+
+ +

通常将代码语句按照层级缩进以及对缩进进行复核会有助于错误的发现。

+ +
(function() {
+  if (true) {
+    return false;
+  }
+});
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_curly_after_property_list/index.html b/files/zh-cn/web/javascript/reference/errors/missing_curly_after_property_list/index.html new file mode 100644 index 0000000000..4c6a06e4e0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_curly_after_property_list/index.html @@ -0,0 +1,51 @@ +--- +title: 'SyntaxError: missing } after property list' +slug: Web/JavaScript/Reference/Errors/Missing_curly_after_property_list +tags: + - Errors + - JavaScript + - SyntaxError +translation_of: Web/JavaScript/Reference/Errors/Missing_curly_after_property_list +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
SyntaxError: missing } after property list
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

对象初始化的时候语法出错了。可能是遗漏了一个大括号,也可能是遗漏了逗号。还要检查是否以正确的顺序关闭了大括号或括号。 缩进或格式化代码也许可以更好帮助你看清这些芜杂的。

+ +

示例

+ +

遗漏的逗号

+ +

很多情况下,对象初始值代码会中缺少逗号:

+ +
var obj = {
+  a: 1,
+  b: { myProp: 2 }
+  c: 3
+};
+
+ +

正确的是:

+ +
var obj = {
+  a: 1,
+  b: { myProp: 2 },
+  c: 3
+};
+
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_formal_parameter/index.html b/files/zh-cn/web/javascript/reference/errors/missing_formal_parameter/index.html new file mode 100644 index 0000000000..9d8a069258 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_formal_parameter/index.html @@ -0,0 +1,80 @@ +--- +title: 'SyntaxError: missing formal parameter' +slug: Web/JavaScript/Reference/Errors/Missing_formal_parameter +tags: + - JavaScript + - 类型错误 + - 错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Missing_formal_parameter +--- +
{{jsSidebar("Errors")}}
+ +

信息提示

+ +
SyntaxError: missing formal parameter (Firefox)
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

“形式参数” 是 “函数参数”一种更好的说法。函数声明缺少合法的参数定义。在函数声明中,参数定义必须为标记符({{Glossary("Identifier", "identifiers")}}), 而不是任何类似于数字、字符串或者对象的值。函数声明和函数调用是两个不同的步骤。函数声明中的参数需要使用标记符,而仅仅在函数被呼叫(调用)的时候才可以传入其所需要的值。

+ +

在 {{glossary("JavaScript")}} 中,标记符只能由字母、数字、"$" 以及 "_" 构成,并且不能以数字开头。标记符与字符串的区别在于字符串是数据,而标记符属于代码的一部分。

+ +

示例

+ +

在构造一个函数的时候,函数参数必须为标记符。下面列举的函数声明都是无效的,因为它们在参数部分使用的是数值:

+ +
function square(3) {
+  return number * number;
+};
+// SyntaxError: missing formal parameter
+
+function greet("Howdy") {
+  return greeting;
+};
+// SyntaxError: missing formal parameter
+
+function log({ obj: "value"}) {
+  console.log(arg)
+};
+// SyntaxError: missing formal parameter
+
+ +

需要在函数声明中使用标记符:

+ +
function square(number) {
+  return number * number;
+};
+
+function greet(greeting) {
+  return greeting;
+};
+
+function log(arg) {
+  console.log(arg)
+};
+ +

之后可以传入你想要传入的实际参数调用函数:

+ +
square(2); // 4
+
+greet("Howdy"); // "Howdy"
+
+log({obj: "value"}); // Object { obj: "value" }
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_initializer_in_const/index.html b/files/zh-cn/web/javascript/reference/errors/missing_initializer_in_const/index.html new file mode 100644 index 0000000000..f87d78f746 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_initializer_in_const/index.html @@ -0,0 +1,57 @@ +--- +title: 'SyntaxError: missing = in const declaration' +slug: Web/JavaScript/Reference/Errors/Missing_initializer_in_const +tags: + - JavaScript + - 语法错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Missing_initializer_in_const +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: missing = in const declaration (Firefox)
+SyntaxError: Missing initializer in const declaration (Chrome)
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

常量指的是在程序正常运行过程中不能被修改的值。它的值不能通过二次赋值来改变,同时也不能被再次声明。在 JavaScript 中,常量在声明时使用  const 关键字来修饰。常量需要初始化器;也就是说,必须在声明的同时为其赋值(鉴于常量值指定之后不能再进行修改,这样做是容易理解的)。

+ +

示例

+ +

初始值缺失

+ +

不同于 var 或 let 关键字,必须在常量声明中为其赋值。下面的例子中会报错:

+ +
const COLUMNS;
+// SyntaxError: missing = in const declaration
+ +

错误修正

+ +

修正这个问题的方法有很多种。仔细检查对于问题中的常量,你想要达到什么目标。

+ +

添加常量值

+ +

在声明语句中为其赋值:

+ +
const COLUMNS = 80;
+ +

const, let 还是 var?

+ +

如果你并不想声明一个常量值,那么就不要使用 const 关键字。或许你想要的是使用  let 来声明一个块状作用域变量或者是用 var 声明一个全局变量。这两者都不需要设置初始值。

+ +
let columns;
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_name_after_dot_operator/index.html b/files/zh-cn/web/javascript/reference/errors/missing_name_after_dot_operator/index.html new file mode 100644 index 0000000000..634008c21b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_name_after_dot_operator/index.html @@ -0,0 +1,67 @@ +--- +title: 'SyntaxError: missing name after . operator' +slug: Web/JavaScript/Reference/Errors/Missing_name_after_dot_operator +tags: + - JavaScript + - 语法错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Missing_name_after_dot_operator +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: missing name after . operator
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

点操作符 (.) 用于属性访问。你需要指定要访问的属性名称。对于属性名称是运算表达式的属性访问,需要将属性访问的方式从点操作符转换为方括号操作符。这样你就可以在其中进行表达式运算了。或许你想要进行字符串拼接操作?那么请使用加号操作符(+)。请参考下面的示例。

+ +

示例

+ +

属性访问

+ +

在 JavaScript 中,属性访问器或者使用点操作符 (.),或者使用方括号操作符 ([]),但是二者不能同时使用。方括号操作符允许属性名称为运算表达式的属性访问。

+ +
var obj = { foo: { bar: "baz", bar2: "baz2" } };
+var i = 2;
+
+obj.[foo].[bar]
+// SyntaxError: missing name after . operator
+
+obj.foo."bar"+i;
+// SyntaxError: missing name after . operator
+
+ +

为了进行代码修复,你需要向下面这样来访问对象:

+ +
obj.foo.bar; // "baz"
+// or alternatively
+obj["foo"]["bar"]; // "baz"
+
+// computed properties require square brackets
+obj.foo["bar" + i]; // "baz2"
+
+ +

属性访问与字符串拼接

+ +

如果你是中其他编程语言(如 {{Glossary("PHP")}})转到 JavaScript 的,很容易将点操作符 (.) 与连接操作符 (+) 混用:

+ +
console.log("Hello" . "world");
+
+// SyntaxError: missing name after . operator
+ +

相反要使用加号来进行字符串拼接:

+ +
console.log("Hello" + "World");
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_parenthesis_after_argument_list/index.html b/files/zh-cn/web/javascript/reference/errors/missing_parenthesis_after_argument_list/index.html new file mode 100644 index 0000000000..5d3dfe8809 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_parenthesis_after_argument_list/index.html @@ -0,0 +1,42 @@ +--- +title: 'SyntaxError: missing ) after argument list' +slug: Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list +tags: + - JavaScript + - 语法错误 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
语法错误: 参数列表后面缺少 )
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}.

+ +

什么地方出错了?

+ +

有一个函数在调用时出现错误。这可能是一个错误,丢失运算符或者转义字符等。

+ +

示例

+ +

因为没有使用 ”+“ 操作符来连接字符串,JavaScript 认为 log 函数的参数的值只是 “PI: ”,在这种情况下,它应该用一个右括号作为结束。

+ +
console.log("PI: " Math.PI);
+// SyntaxError: missing ) after argument list
+
+ +

你可以正确的调用 log 函数通过加上 ”+“ 操作符。

+ +
console.log("PI: " + Math.PI);
+// "PI: 3.141592653589793"
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_parenthesis_after_condition/index.html b/files/zh-cn/web/javascript/reference/errors/missing_parenthesis_after_condition/index.html new file mode 100644 index 0000000000..e2db63da04 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_parenthesis_after_condition/index.html @@ -0,0 +1,69 @@ +--- +title: 'SyntaxError: missing ) after condition' +slug: Web/JavaScript/Reference/Errors/Missing_parenthesis_after_condition +tags: + - JavaScript + - 语法错误 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Missing_parenthesis_after_condition +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: missing ) after condition
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

这个错误与 if 条件语句是如何写的有关。在任何编程语言中,代码都需要做出一些判断,然后根据不同的判断结果来执行不同的操作。if 语句会在其指定的判断条件为真的时候执行。在 JavaScript 中,条件表达式必须出现在 if 关键字后面的一对括号中,像下面这样:

+ +
if (condition) {
+  // do something if the condition is true
+}
+ +

示例

+ +

下面这种情况的出现可能只是出于大意,需要仔细检查代码中的括号。

+ +
if (3 > Math.PI {
+  console.log("wait what?");
+}
+
+// SyntaxError: missing ) after condition
+
+ +

修复代码的方法就是添加闭合条件表达式的右括号。

+ +
if (3 > Math.PI) {
+  console.log("wait what?");
+}
+ +

如果你是从其他语言转到 JavaScript 的,那么很容易在 JavaScript 中使用与之含义不同或者没有任何意义的关键字。

+ +
if (done is true) {
+ console.log("we are done!");
+}
+
+// SyntaxError: missing ) after condition
+
+ +

相反你需要使用正确的比较操作符, 如下:

+ +
if (done === true) {
+ console.log("we are done!");
+}
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/missing_semicolon_before_statement/index.html b/files/zh-cn/web/javascript/reference/errors/missing_semicolon_before_statement/index.html new file mode 100644 index 0000000000..e3e6a98c88 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/missing_semicolon_before_statement/index.html @@ -0,0 +1,81 @@ +--- +title: 'SyntaxError: missing ; before statement' +slug: Web/JavaScript/Reference/Errors/Missing_semicolon_before_statement +translation_of: Web/JavaScript/Reference/Errors/Missing_semicolon_before_statement +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
SyntaxError: Expected ';' (Edge)
+ +
 SyntaxError: missing ; before statement (Firefox)
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}.

+ +

哪里出错了?

+ +

某个地方丢失了一个(;)。 JavaScript 语句必须以分号结束。 有一些是由 自动分号插入(ASI) 的使用所影响到的, 但在这种情况下,你需要提供一个分号,以便于JavaScript可以将源代码解析正确。然而,通常情况下,这个错误只是另一个错误一个导致的,如不正确转义字符串,使用var的错误。你也可能有太多的括号的地方。当出现此错误时,仔细检查语法。

+ +

例子

+ +

 

+ +

转义字符串

+ +

这个错误可能发生不正确时容易转义字符串JavaScript引擎是希望你的字符串的末尾已经。例如:

+ +
var foo = 'Tom's bar';
+// SyntaxError: missing ; before statement
+ +

你可以用双引号,或者用\转义:

+ +
var foo = "Tom's bar";
+var foo = 'Tom\'s bar';
+
+ +

用var声明属性

+ +

你不能将带有变量声明的对象或数组的属性用var来声明。

+ +
var obj = {};
+var obj.foo = "hi"; // SyntaxError missing ; before statement
+
+var array = [];
+var array[0] = "there"; // SyntaxError missing ; before statement
+
+ +

而是省略掉var关键词:

+ +
var obj = {};
+obj.foo = "hi";
+
+var array = [];
+array[0] = "there";
+
+ +

不推荐使用的关键字

+ +

如果你用的是另一种编程语言,那么在javaScript中使用不具有相同或完全没有意义的关键字也是很常见的:

+ +
def print(info){
+  console.log(info);
+}; // SyntaxError missing ; before statement
+ +

因此,建议使用function而不是def

+ +
function print(info){
+  console.log(info);
+};
+ +

 

+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/more_arguments_needed/index.html b/files/zh-cn/web/javascript/reference/errors/more_arguments_needed/index.html new file mode 100644 index 0000000000..b042af14bb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/more_arguments_needed/index.html @@ -0,0 +1,48 @@ +--- +title: 'TypeError: More arguments needed' +slug: Web/JavaScript/Reference/Errors/More_arguments_needed +tags: + - Errors + - JavaScript + - TypeError +translation_of: Web/JavaScript/Reference/Errors/More_arguments_needed +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
TypeError: Object.create requires more than 0 arguments
+TypeError: Object.setPrototypeOf requires more than 1 argument
+TypeError: Object.defineProperties requires more than 0 arguments
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}.

+ +

哪里出错了?

+ +

调用函数的时候出现了错误。需要提供更多的参数。

+ +

示例

+ +

{{jsxref("Object.create()")}} 方法要求至少有一个参数,而 {{jsxref("Object.setPrototypeOf()")}} 方法要求至少有两个参数:

+ +
var obj = Object.create();
+// TypeError: Object.create requires more than 0 arguments
+
+var obj = Object.setPrototypeOf({});
+// TypeError: Object.setPrototypeOf requires more than 1 argument
+
+ +

你可以将 {{jsxref("null")}} 设置为原型:

+ +
var obj = Object.create(null);
+
+var obj = Object.setPrototypeOf({}, null);
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/negative_repetition_count/index.html b/files/zh-cn/web/javascript/reference/errors/negative_repetition_count/index.html new file mode 100644 index 0000000000..780bdabcf4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/negative_repetition_count/index.html @@ -0,0 +1,45 @@ +--- +title: 'RangeError: repeat count must be non-negative' +slug: Web/JavaScript/Reference/Errors/Negative_repetition_count +tags: + - Errors + - JavaScript + - RangeError + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Negative_repetition_count +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
RangeError: repeat count must be non-negative (Firefox)
+RangeError: Invalid count value (Chrome)
+
+ +

错误类型

+ +

{{jsxref("RangeError")}}

+ +

发生了什么?

+ +

代码中使用了 {{jsxref("String.prototype.repeat()")}}方法。它有一个计数参数,表示重复该字符串的次数。该参数必须在 0 及正 {{jsxref("Infinity")}} 之间,且不能为负数。该值的合法范围可以这样表示: [0, +∞)。

+ +

示例

+ +

无效的

+ +
'abc'.repeat(-1); // RangeError 
+ +

有效的

+ +
'abc'.repeat(0);    // ''
+'abc'.repeat(1);    // 'abc'
+'abc'.repeat(2);    // 'abcabc'
+'abc'.repeat(3.5);  // 'abcabcabc' (count will be converted to integer)
+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/no_non-null_object/index.html b/files/zh-cn/web/javascript/reference/errors/no_non-null_object/index.html new file mode 100644 index 0000000000..6369e8eaf1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/no_non-null_object/index.html @@ -0,0 +1,65 @@ +--- +title: 'TypeError: "x" is not a non-null object' +slug: Web/JavaScript/Reference/Errors/No_non-null_object +tags: + - JavaScript + - 类型错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/No_non-null_object +--- +
{{JSSidebar("Errors")}}
+ +

提示信息

+ +
TypeError: "x" is not a non-null object (Firefox)
+TypeError: Property description must be an object: "x" (Chrome)
+TypeError: Invalid value used in weak set (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

在期待出现对象类型的值的地方而没有提供。{{jsxref("null")}} 不是对象类型,因此不起作用。必须在给定的场景下提供一个合适的对象。

+ +

示例

+ +

期望的属性描述器

+ +

当使用诸如 {{jsxref("Object.create()")}} 或 {{jsxref("Object.defineProperty()")}} 及{jsxref("Object.defineProperties()")}} 方法时,可选的属性描述器参数需要提供一个描述器对象。提供非对象类型的值(例如数字)将会报错:

+ +
Object.defineProperty({}, 'key', 1);
+// TypeError: 1 is not a non-null object
+
+Object.defineProperty({}, 'key', null);
+// TypeError: null is not a non-null object
+
+ +

一个合法的描述器对象类似于下面这样:

+ +
Object.defineProperty({}, 'key', { value: 'foo', writable: false });
+
+ +

WeakMap 和 WeakSet 对象需要对象类型的键

+ +

{{jsxref("WeakMap")}} 和 {{jsxref("WeakSet")}} 对象只能存储对象类型的键,而不能使用其他类型的。

+ +
var ws = new WeakSet();
+ws.add('foo');
+// TypeError: "foo" is not a non-null object
+ +

用对象类型的值来替换:

+ +
ws.add({foo: 'bar'});
+ws.add(window);
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/no_properties/index.html b/files/zh-cn/web/javascript/reference/errors/no_properties/index.html new file mode 100644 index 0000000000..5e904dd8ab --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/no_properties/index.html @@ -0,0 +1,36 @@ +--- +title: 'TypeError: "x" has no properties' +slug: Web/JavaScript/Reference/Errors/No_properties +translation_of: Web/JavaScript/Reference/Errors/No_properties +--- +
{{jsSidebar("Errors")}}
+ +

错误信息

+ +
TypeError: null has no properties
+TypeError: undefined has no properties
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}.

+ +

哪里出错了?

+ +

 {{jsxref("null")}} 和 {{jsxref("undefined")}}中,没有你需要的属性。

+ +

例子

+ +
null.foo;
+// 错误类型: null没有这个属性
+
+undefined.bar;
+// 错误类型: undefined没有这个属性
+
+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/no_variable_name/index.html b/files/zh-cn/web/javascript/reference/errors/no_variable_name/index.html new file mode 100644 index 0000000000..4b69a5cec1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/no_variable_name/index.html @@ -0,0 +1,83 @@ +--- +title: 'SyntaxError: missing variable name' +slug: Web/JavaScript/Reference/Errors/No_variable_name +tags: + - JavaScript + - 语法错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/No_variable_name +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: missing variable name (Firefox)
+SyntaxError: Unexpected token = (Chrome)
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

缺失变量名。这有很大的可能性是由你的代码中的语法错误造成的。也许是什么地方的逗号出了问题,或者是你正在绞尽脑汁想一个合适的名字。完全可以理解!为变量起名确实让人头疼。

+ +

示例

+ +

变量名缺失

+ +
var = "foo";
+
+ +

为变量起一个合适的明确确实不是一件容易的事情。这种经历每个人都遇到过。

+ +
var ohGodWhy = "foo";
+ +

保留字不能作为变量名

+ +

有一些名称是作为保留字而存在的。不好意思,你不能使用!:(

+ +
var debugger = "whoop";
+// SyntaxError: missing variable name
+
+ +

一次性声明多个变量

+ +

在一次性声明多个变量的时候要特别留意逗号。看看是否有多余的逗号?以及是否不小心把逗号用作了分号?

+ +
var x, y = "foo",
+var x, = "foo"
+
+var first = document.getElementById('one'),
+var second = document.getElementById('two'),
+
+// SyntaxError: missing variable name
+
+ +

修复后的代码:

+ +
var x, y = "foo";
+var x = "foo";
+
+var first = document.getElementById('one');
+var second = document.getElementById('two');
+ +

数组

+ +

在 JavaScript 中 {{jsxref("Array")}} 字面量需要使用方括号将值包裹起来。下面这样是不对的:

+ +
var arr = 1,2,3,4,5;
+// SyntaxError: missing variable name
+
+ +

这样写才是正确的:

+ +
var arr = [1,2,3,4,5];
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/non_configurable_array_element/index.html b/files/zh-cn/web/javascript/reference/errors/non_configurable_array_element/index.html new file mode 100644 index 0000000000..d38da28248 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/non_configurable_array_element/index.html @@ -0,0 +1,81 @@ +--- +title: 'TypeError: can''t delete non-configurable array element' +slug: Web/JavaScript/Reference/Errors/Non_configurable_array_element +tags: + - JavaScript + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Non_configurable_array_element +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
TypeError: can't delete non-configurable array element (Firefox)
+TypeError: Cannot delete property '2' of [object Array] (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

这个错误提示发生于当试图缩短一个数组的长度的时候,其中有元素是不可配置的(non-configurable)。正常情况下,缩短数组的长度,则超出限度的元素会被删除,而这里指的是这种操作失效的情况。

+ +

 configurable  特性控制着属性是否可以从对象中删除,以及它的特性(除了 writable 之外)是否可以发生改变。

+ +

通常,使用数组初始化语句创建的对象是可配置的,而通过 {{jsxref("Object.defineProperty()")}} 创建的属性,默认则是不可配置的。

+ +

示例

+ +

通过 Object.defineProperty 创建的不可配置属性

+ +

使用 {{jsxref("Object.defineProperty()")}} 且在没有明确将属性设定为可配置的情况下,默认可以创建不可配置属性。

+ +
var arr = [];
+Object.defineProperty(arr, 0, {value: 0});
+Object.defineProperty(arr, 1, {value: "1"});
+
+arr.length = 1;
+// TypeError: can't delete non-configurable array element
+
+ +

如果想要缩短数组长度的话,需要将其中的元素设置为可配置的。

+ +
var arr = [];
+Object.defineProperty(arr, 0, {value: 0, configurable: true});
+Object.defineProperty(arr, 1, {value: "1", configurable: true});
+
+arr.length = 1;
+
+ +

密封的数组

+ +

 {{jsxref("Object.seal()")}} 函数会将数组中现存的所有元素标记为不可配置。

+ +
var arr = [1,2,3];
+Object.seal(arr);
+
+arr.length = 1;
+// TypeError: can't delete non-configurable array element
+
+ +

(为了解决上述问题,)或者是移除 {{jsxref("Object.seal()")}} 调用,或者将数组拷贝一份。在拷贝数组的情况下,缩短备份数组的长度并不会修改原始数组的长度。

+ +
var arr = [1,2,3];
+Object.seal(arr);
+
+// Copy the initial array to shorten the copy
+var copy = Array.from(arr);
+copy.length = 1;
+// arr.length == 3
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/not_a_codepoint/index.html b/files/zh-cn/web/javascript/reference/errors/not_a_codepoint/index.html new file mode 100644 index 0000000000..769e6daa0c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/not_a_codepoint/index.html @@ -0,0 +1,51 @@ +--- +title: 'RangeError: argument is not a valid code point' +slug: Web/JavaScript/Reference/Errors/Not_a_codepoint +translation_of: Web/JavaScript/Reference/Errors/Not_a_codepoint +--- +
{{jsSidebar("Errors")}}
+ +

错误信息

+ +
RangeError: {0} is not a valid code point (Firefox)
+RangeError: Invalid code point {0} (Chrome)
+
+ +

错误类型

+ +

{{jsxref("RangeError")}}

+ +

什么地方出错了?

+ +

 {{jsxref("String.fromCodePoint()")}} 这个方法只能接受有效的码位(code point) 。

+ +

码位( code point)是组成码空间(或代码页)的数值,范围是 0 到 0x10FFFF。

+ +

 {{jsxref("NaN")}},负整数(-1),非整数(3.14),或编号大于0x10FFFF (1114111) 的字符,无法使用该方法。

+ +

范例

+ +

无效的例子

+ +
String.fromCodePoint('_');      // RangeError
+String.fromCodePoint(Infinity); // RangeError
+String.fromCodePoint(-1);       // RangeError
+String.fromCodePoint(3.14);     // RangeError
+String.fromCodePoint(3e-2);     // RangeError
+String.fromCodePoint(NaN);      // RangeError
+ +

有效的例子

+ +
String.fromCodePoint(42);       // "*"
+String.fromCodePoint(65, 90);   // "AZ"
+String.fromCodePoint(0x404);    // "\u0404"
+String.fromCodePoint(0x2F804);  // "\uD87E\uDC04"
+String.fromCodePoint(194564);   // "\uD87E\uDC04"
+String.fromCodePoint(0x1D306, 0x61, 0x1D307) // "\uD834\uDF06a\uD834\uDF07"
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/not_a_constructor/index.html b/files/zh-cn/web/javascript/reference/errors/not_a_constructor/index.html new file mode 100644 index 0000000000..60279ed3c8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/not_a_constructor/index.html @@ -0,0 +1,95 @@ +--- +title: 'TypeError: "x" is not a constructor' +slug: Web/JavaScript/Reference/Errors/Not_a_constructor +tags: + - Errors + - JavaScript + - TypeError +translation_of: Web/JavaScript/Reference/Errors/Not_a_constructor +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
TypeError: "x" is not a constructor
+
+TypeError: Math is not a constructor
+TypeError: JSON is not a constructor
+TypeError: Symbol is not a constructor
+TypeError: Reflect is not a constructor
+TypeError: Intl is not a constructor
+TypeError: SIMD is not a constructor
+TypeError: Atomics is not a constructor
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

是因为尝试将不是构造器的对象或者变量来作为构造器使用。参考 {{Glossary("constructor")}} 或者 new operator 来了解什么是构造器。

+ +

有很多的全局对象比如 {{jsxref("String")}}、{{jsxref("Array")}} 等等都是可以使用 new 操作符的构造器。但是有一些全局对象并不是,且其属性和方法都是静态的。下面的 JavaScript 标准内置对象都不是构造器:{{jsxref("Math")}},{{jsxref("JSON")}},{{jsxref("Symbol")}},{{jsxref("Reflect")}},{{jsxref("Intl")}},{{jsxref("SIMD")}},{{jsxref("Atomics")}}。

+ +

Generator functions 也不能作为构造器来使用。

+ +

示例

+ +

无效的

+ +
var Car = 1;
+new Car();
+// TypeError: Car is not a constructor
+
+new Math();
+// TypeError: Math is not a constructor
+
+new Symbol();
+// TypeError: Symbol is not a constructor
+
+function* f() {};
+var obj = new f;
+// TypeError: f is not a constructor
+
+ +

一个构造器

+ +

假设你想为汽车创建一个对象类型。 你希望此类型的对象被称为 car,并且您希望它具有make,model 和 year 属性。 为此,你编写以下函数:

+ +
function Car(make, model, year) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+}
+
+ +

现在你可以创建一个名为 mycar 的对象,如下所示:

+ +
var mycar = new Car("Eagle", "Talon TSi", 1993);
+ +

关于 Promises 

+ +

当返回了一个 immediately-resolved 或者 immediately-rejected Promise 的时候,你根本不需要去创建、操作一个新的 Promise 对象。

+ +

这是不合法的(Promise constructor 被错误的调用了)且会抛出一个 错误 TypeError: this is not a constructor exception:

+ +
return new Promise.resolve(true);
+
+ +

使用 Promise.resolve() 或者 Promise.reject() 静态方法来代替:

+ +
// 这是合法的,但是没必要这么长:
+return new Promise((resolve, reject) => { resolve(true); })
+
+// 用静态方法来代替:
+return Promise.resolve(true);
+return Promise.reject(false);
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/not_a_function/index.html b/files/zh-cn/web/javascript/reference/errors/not_a_function/index.html new file mode 100644 index 0000000000..fc4f664e1d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/not_a_function/index.html @@ -0,0 +1,167 @@ +--- +title: 'TypeError: "x" is not a function' +slug: Web/JavaScript/Reference/Errors/Not_a_function +tags: + - Errors + - JavaScript + - TypeError +translation_of: Web/JavaScript/Reference/Errors/Not_a_function +--- +
{{jsSidebar("Errors")}}
+ +
JavaScript异常"is not a function"会在试图去调用一个像函数一样的值,但是该值实际上不是函数时被抛出.
+ +

信息

+ +
TypeError: Object doesn't support property or method {x} (Edge)
+TypeError: "x" is not a function
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

问题出在你试图去调用一个像函数一样的值,但是该值实际上不是函数,有时候你的代码需要调用一些函数,但是那种值并不能当作函数来被调用。

+ +

也许函数名称上有错别字? 也许你正在调用Object对象没有这个方法? 例如,在JavaScript中单纯的对象(Object)没有map函数,但是JavaScript数组(Array)对象却有这个函数。

+ +

再比如,在JavaScript中很多原生对象的内置方法需要你提供一个(回调)函数。 所以你必须提供一个函数,以使这些方法正常工作:

+ + + +

例子

+ +

函数的名称错误

+ +

函数的名称拼写错误,这种情况是经常发生的:

+ +
var x = document.getElementByID("foo");
+// TypeError: document.getElementByID is not a function
+
+ +

正确的方法名应该是 getElementById:

+ +
var x = document.getElementById("foo");
+
+ +

调用Object类型中不存在的方法

+ +

对于某些特殊的方法,它只属于某些特定的原生对象中,你必须提供一个回调函数才能正常运行。例如:这里调用了一个 {{jsxref("Array.prototype.map()")}} 方法,但是这方法只能被 {{jsxref("Array")}} 对象所调用。 

+ +
var obj = { a: 13, b: 37, c: 42 };
+
+obj.map(function(num) {
+  return num * 2;
+});
+
+// TypeError: obj.map is not a function
+ +

正确的做法,使用一个数组来代替:

+ +
var numbers = [1, 4, 9];
+
+numbers.map(function(num) {
+  return num * 2;
+});
+
+// Array [ 2, 8, 18 ]
+
+ +

函数与已有属性重名

+ +

当您在创建类时,可能会存在某个属性和某个方法的名称相同,当您在调用该函数时,编译器会认为该函数不存在.

+ +
var Dog = function () {
+ this.age = 11;
+ this.color = "black";
+ this.name = "Ralph";
+ return this;
+}
+
+Dog.prototype.name = function(name) {
+ this.name = name;
+ return this;
+}
+
+
+var myNewDog = new Dog();
+myNewDog.name("Cassidy"); //Uncaught TypeError: myNewDog.name is not a function
+
+ +

正确的做法是使用不同的变量名.

+ +
var Dog = function () {
+ this.age = 11;
+ this.color = "black";
+ this.dogName = "Ralph"; //Using this.dogName instead of .name
+ return this;
+}
+
+Dog.prototype.name = function(name) {
+ this.dogName = name;
+ return this;
+}
+
+
+var myNewDog = new Dog();
+myNewDog.name("Cassidy"); //Dog { age: 11, color: 'black', dogName: 'Cassidy' }
+ +

使用括号进行乘法运算

+ +

在数学中,您可以将 2 × (3 + 5) 写为 2*(3 + 5) 或者省略为 2(3 + 5).

+ +

使用后者时将会抛出错误:

+ +
const sixteen = 2(3 + 5);
+alert('2 x (3 + 5) is ' + String(sixteen));
+//Uncaught TypeError: 2 is not a function
+ +

您可以添加乘法运算符 * 来改正代码:

+ +
const sixteen = 2 * (3 + 5);
+alert('2 x (3 + 5) is ' + String(sixteen));
+//2 x (3 + 5) is 16
+ +

正确地导入和导出模块

+ +

确保正确导入模块.

+ +

以下为一个示例模块 (helpers.js)

+ +
let helpers = function () { };
+
+helpers.groupBy = function (objectArray, property) {
+  return objectArray.reduce(function (acc, obj) {
+    var key = obj[property];
+    if (!acc[key]) {
+      acc[key] = [];
+    }
+    acc[key].push(obj);
+    return acc;
+  },
+{});
+}
+
+export default helpers;
+ +

在 App.js中正确导入该模块:

+ +
import helpers from './helpers'
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/not_defined/index.html b/files/zh-cn/web/javascript/reference/errors/not_defined/index.html new file mode 100644 index 0000000000..a092f394ec --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/not_defined/index.html @@ -0,0 +1,66 @@ +--- +title: 'ReferenceError: "x" is not defined' +slug: Web/JavaScript/Reference/Errors/Not_defined +translation_of: Web/JavaScript/Reference/Errors/Not_defined +--- +

{{jsSidebar("Errors")}}

+ +

错误信息

+ +
ReferenceError: "x" is not defined
+
+ +

错误类型

+ +

{{jsxref("ReferenceError")}}.

+ +

什么地方出错了?

+ +

在某些地方引用一个不存在的变量的时候。当你使用变量的时候,这个变量必须是已经被声明的,或者你可以确保它在你当前的脚本或作用域 ({{Glossary("scope")}}) 中可用。

+ +
+

注意: 当你加载一个库的时候(例如 jQuery),请确保你在这个库加载完毕后再使用这个库中的变量,如“$”。将你想加载的库的 {{HTMLElement("script")}} 标签放置在你的代码前面。

+
+ +

示例

+ +

变量没有被声明

+ +
foo.substring(1); // ReferenceError: foo is not defined
+
+ +

“foo” 变量没有在任何地方被声明。它需要是某种字符串,这样 {{jsxref("String.prototype.substring()")}} 方法才可以正常工作。

+ +
var foo = 'bar';
+foo.substring(1); // "ar"
+ +

错误的作用域

+ +

变量必须是在它当前的执行环境中可用的。在一个函数(function)中定义的变量不能从这个函数外部的任何地方访问,因为这个变量的作用域仅在这个函数的内部。

+ +
function numbers () {
+  var num1 = 2,
+      num2 = 3;
+  return num1 + num2;
+}
+
+console.log(num1); // ReferenceError num1 is not defined.
+ +

然而,一个函数可用使用在它所被定义的作用域中的所有变量。换句话说,当一个函数被定义在全局作用域的时候,它可以访问所有在全局作用域中定义的变量。

+ +
var num1 = 2,
+    num2 = 3;
+
+function numbers () {
+  return num1 + num2;
+}
+
+console.log(num1); // 2
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/precision_range/index.html b/files/zh-cn/web/javascript/reference/errors/precision_range/index.html new file mode 100644 index 0000000000..42e2c703a9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/precision_range/index.html @@ -0,0 +1,96 @@ +--- +title: 'RangeError: precision is out of range' +slug: Web/JavaScript/Reference/Errors/Precision_range +tags: + - JavaScript + - 范围错误 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Precision_range +--- +
{{jsSidebar("Errors")}}
+ +

描述

+ +
RangeError: precision {0} out of range (Firefox)
+RangeError: toExponential() argument must be between 0 and 20 (Chrome)
+RangeError: toFixed() digits argument must be between 0 and 20 (Chrome)
+RangeError: toPrecision() argument must be between 1 and 21 (Chrome)
+
+ +

错误类型

+ +

{{jsxref("RangeError")}}

+ +

什么地方出错了?

+ +

以下的某个方法传入了一个超出精度范围的参数:

+ + + +

通常这些方法允许的参数范围介于0和20(或21)之间。需要注意的是,ECMAScript标准是允许扩展这个范围的。

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodFirefox (SpiderMonkey)Chrome, Opera (V8)
{{jsxref("Number.prototype.toExponential()")}}0 to 1000 to 20
{{jsxref("Number.prototype.toFixed()")}}-20 to 1000 to 20
{{jsxref("Number.prototype.toPrecision()")}}1 to 1001 to 21
+ +

示例

+ +

错误的示例

+ +
77.1234.toExponential(-1);  // RangeError
+77.1234.toExponential(101); // RangeError
+
+2.34.toFixed(-100);         // RangeError
+2.34.toFixed(1001);         // RangeError
+
+1234.5.toPrecision(-1);     // RangeError
+1234.5.toPrecision(101);    // RangeError
+
+ +

正确的示例

+ +
77.1234.toExponential(4); // 7.7123e+1
+77.1234.toExponential(2); // 7.71e+1
+
+2.34.toFixed(1); // 2.3
+2.35.toFixed(1); // 2.4 (note that it rounds up in this case)
+
+5.123456.toPrecision(5); // 5.1235
+5.123456.toPrecision(2); // 5.1
+5.123456.toPrecision(1); // 5
+
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/property_access_denied/index.html b/files/zh-cn/web/javascript/reference/errors/property_access_denied/index.html new file mode 100644 index 0000000000..7b90b8be6f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/property_access_denied/index.html @@ -0,0 +1,45 @@ +--- +title: 'Error: Permission denied to access property "x"' +slug: Web/JavaScript/Reference/Errors/Property_access_denied +tags: + - Error + - Permission denied + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Property_access_denied +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
Error: Permission denied to access property "x"
+
+ +

错误类型

+ +

{{jsxref("Error","错误")}}.

+ +

什么地方出错了?

+ +

尝试访问无权访问的对象。这很可能出现在使用{{HTMLElement("iframe")}}元素时加载了一个不同域名下的页面,这在访问子页面时会违背同源策略

+ +

示例

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <iframe id="myframe" src="http://www1.w3c-test.org/common/blank.html"></iframe>
+    <script>
+      console.log(document.getElementById('myframe').contentWindow.document);
+      // Error: Permission denied to access property "document"
+    </script>
+  </head>
+  <body></body>
+</html>
+
+ +

可以参考

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/read-only/index.html b/files/zh-cn/web/javascript/reference/errors/read-only/index.html new file mode 100644 index 0000000000..ecdc225497 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/read-only/index.html @@ -0,0 +1,76 @@ +--- +title: 'TypeError: "x" is read-only' +slug: Web/JavaScript/Reference/Errors/Read-only +translation_of: Web/JavaScript/Reference/Errors/Read-only +--- +
{{jsSidebar("Errors")}}
+ +

报错消息

+ +
TypeError: "x" is read-only (Firefox) //格式错误:"x"只读。(x可以代表任意值)
+TypeError: 0 is read-only (Firefox)
+TypeError: Cannot assign to read only property 'x' of #<Object> (Chrome)
+//格式错误:对象的x属性是只读的不能设置 (chrome)
+TypeError: Cannot assign to read only property '0' of [object Array] (Chrome)
+
+ +

错误格式

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

全局变量或对象属性被设置为只读 (专业点讲,就是这条数据属性禁止写入.)

+ +

这条错误值发生在strict mode code(俗称严格模式). 正常情况下,是没有报错的。

+ +

例如

+ +

无效例子(也就是下面这么做会导致报这种错)

+ +

只读属性不能直接创建, 但我们可以通过{{jsxref("Object.defineProperty()")}} 或 {{jsxref("Object.freeze()")}}设置.

+ +
"use strict";
+var obj = Object.freeze({name: "Elsa", score: 157});
+obj.score = 0;  // TypeError
+
+"use strict";
+Object.defineProperty(this, "LUNG_COUNT", {value: 2, writable: false});
+LUNG_COUNT = 3;  // TypeError
+
+"use strict";
+var frozenArray = Object.freeze([0, 1, 2]);
+frozenArray[0]++;  // TypeError
+
+还有几个JavaScript内置属性. 如果你尝试修改一个常量.
+
+"use strict";
+Math.PI = 4;  // TypeError
+ +

傻了吧,报错了

+ +

全局变量undefined也是只读的, 所以你不能忽视臭名昭著的"undefined is not a function"错误:

+ +
"use strict";
+undefined = function () {};  // TypeError: "undefined" is read-only
+
+ +

下面这样都是有效,不报错的

+ +
"use strict";
+var obj = Object.freeze({name: "Score", points: 157});
+obj = {name: obj.name, points: 0};   // 用一个新对象替换原来的对象(其实就是更改了对象的指针)
+
+"use strict";
+var LUNG_COUNT = 2;  //
+LUNG_COUNT = 3;  //
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/redeclared_parameter/index.html b/files/zh-cn/web/javascript/reference/errors/redeclared_parameter/index.html new file mode 100644 index 0000000000..9a53795180 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/redeclared_parameter/index.html @@ -0,0 +1,62 @@ +--- +title: 'SyntaxError: redeclaration of formal parameter "x"' +slug: Web/JavaScript/Reference/Errors/Redeclared_parameter +tags: + - Errors + - JavaScript + - SyntaxError +translation_of: Web/JavaScript/Reference/Errors/Redeclared_parameter +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
SyntaxError: redeclaration of formal parameter "x" (Firefox)
+SyntaxError: Identifier "x" has already been declared (Chrome)
+SyntaxError: Cannot declare a let variable twice: 'x' (WebKit)
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

某个变量名称已经作为函数参数出现了,但是又使用了 let 在函数体里重声明了。在JavaScript 中不允许使用let在相同的函数或块范围内重新声明相同的变量。

+ +

示例

+ +

在本例中,参数 "arg" 又重新声明了:

+ +
function f(arg) {
+  let arg = "foo";
+}
+
+// SyntaxError: redeclaration of formal parameter "arg"
+
+ +

如果要更改函数体中的“arg”的值,可以像下面一样,但不需要再次声明同一个变量。 换句话说:你可以省略 let 关键字。 如果要创建一个新变量,则需要将其重命名,因为其与函数参数有冲突。

+ +
function f(arg) {
+  arg = "foo";
+}
+
+function f(arg) {
+  let bar = "foo";
+}
+
+ +

兼容性提醒

+ + + +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/reduce_of_empty_array_with_no_initial_value/index.html b/files/zh-cn/web/javascript/reference/errors/reduce_of_empty_array_with_no_initial_value/index.html new file mode 100644 index 0000000000..3d90929530 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/reduce_of_empty_array_with_no_initial_value/index.html @@ -0,0 +1,88 @@ +--- +title: 'TypeError: Reduce of empty array with no initial value' +slug: Web/JavaScript/Reference/Errors/Reduce_of_empty_array_with_no_initial_value +tags: + - Error + - JavaScript + - 参考 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Reduce_of_empty_array_with_no_initial_value +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
TypeError: reduce of empty array with no initial value
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出问题了?

+ +

在 JavaScript 中,有一些 reduce 函数:

+ + + +

这些函数有选择性的接收 initialValue (将会被用作回调函数第一次被调用的参数)。然而,如果没有初始值提供,它会用 {{jsxref("Array")}} 或 {{jsxref("TypedArray")}} 的第一个元素作为初始值。当提供一个空数组的时候这个错误会出现,因为那种情况下没有初始值被返回。

+ +

例子

+ +

无效的情况

+ +

当和过滤器({{jsxref("Array.prototype.filter()")}}、{{jsxref("TypedArray.prototype.filter()")}})结合使用的时候,可能会出现列表中所有元素被移除的情况。因此导致初始值为空。

+ +
var ints = [0, -1, -2, -3, -4, -5];
+ints.filter(x => x > 0)         // removes all elements
+    .reduce((x, y) => x + y)    // no more elements to use for the initial value.
+ +

类似的,当选择器中有瑕疵的时候相同的问题会发生,或者是列表中未预期的数量的元素:

+ +
var names = document.getElementsByClassName("names");
+var name_list = Array.prototype.reduce.call(names, (acc, name) => acc + ", " + name);
+
+ +

有效的情况

+ +

这个问题有两种可能的解决办法:

+ +

一种是提供一个初始值作为操作符的中立元素,比如加法里的0,乘法里的1,或者是合并中的一个空字符串。

+ +
var ints = [0, -1, -2, -3, -4, -5];
+ints.filter(x => x < 0)         // removes all elements
+    .reduce((x, y) => x + y, 0) // the initial value is the neutral element of the addition
+
+ +

另一种办法是两方处理空的情况,要么在调用 reduce 之前,或者是在添加一个未预料的初始虚拟址后的回调函数中:

+ +
var names = document.getElementsByClassName("names");
+
+var name_list1 = "";
+if (names1.length >= 1)
+  name_list1 = Array.prototype.reduce.call(names, (acc, name) => acc + ", " + name);
+// name_list1 == "" when names is empty.
+
+var name_list2 = Array.prototype.reduce.call(names, (acc, name) => {
+  if (acc == "") // initial value
+    return name;
+  return acc + ", " + name;
+}, "");
+// name_list2 == "" when names is empty.
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/reserved_identifier/index.html b/files/zh-cn/web/javascript/reference/errors/reserved_identifier/index.html new file mode 100644 index 0000000000..d99acf3fa8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/reserved_identifier/index.html @@ -0,0 +1,79 @@ +--- +title: 'SyntaxError: "x" is a reserved identifier' +slug: Web/JavaScript/Reference/Errors/Reserved_identifier +tags: + - JavaScript + - 语法错误 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Reserved_identifier +--- +
{{jsSidebar("Errors")}}
+ +

消息提示

+ +
SyntaxError: "x" is a reserved identifier (Firefox)
+SyntaxError: Unexpected reserved word (Chrome)
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

保留字 用作标记符将会出错. 这些标记符在严格模式和非严格模式下保留:

+ + + +

以下标记符只会在严格模式下才作为保留字:

+ + + +

示例

+ +

严格与非严格模式下的保留字

+ +

在两种模式下,enum 标识符都会作为保留字。

+ +
var enum = { RED: 0, GREEN: 1, BLUE: 2 };
+// SyntaxError: enum is a reserved identifier
+
+ +

在严格模式下,会有更多的保留字。

+ +
"use strict";
+var package = ["potatoes", "rice", "fries"];
+// SyntaxError: package is a reserved identifier
+
+ +

你需要对上述变量重新命名。

+ +
var colorEnum = { RED: 0, GREEN: 1, BLUE: 2 };
+var list = ["potatoes", "rice", "fries"];
+ +

升级旧版本浏览器

+ +

假如你还在使用尚未支持 let 或 class 等特性的旧版本浏览器,你应该将它们升级到支持这些新语言特性的版本。

+ +
"use strict";
+class DocArchiver {}
+
+// SyntaxError: class is a reserved identifier
+//(只会在旧版本浏览器中抛出,例如 Firefox 44 或更老的版本)
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/resulting_string_too_large/index.html b/files/zh-cn/web/javascript/reference/errors/resulting_string_too_large/index.html new file mode 100644 index 0000000000..eaac0884fb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/resulting_string_too_large/index.html @@ -0,0 +1,50 @@ +--- +title: 'RangeError: repeat count must be less than infinity' +slug: Web/JavaScript/Reference/Errors/Resulting_string_too_large +tags: + - Errors + - JavaScript + - RangeError + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Resulting_string_too_large +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
RangeError: repeat count must be less than infinity and not overflow maximum string size (Firefox)
+
+RangeError: Invalid count value (Chrome)
+
+ +

错误类型

+ +

{{jsxref("RangeError")}}

+ +

发生了什么?

+ +

代码中使用了 {{jsxref("String.prototype.repeat()")}}方法。它有一个计数参数,表示重复该字符串的次数。该参数必须在 0 及正 {{jsxref("Infinity")}} 之间,且不能为负数。该值的合法范围可以这样表示: [0, +∞)。

+ +

其结果字符串也不能长于最大字符串,不同 JavaScript 引擎中可能有所不同。 在 Firefox (SpiderMonkey) 里最大字符串大小为 228 -1 (0xFFFFFFF)。

+ +

示例

+ +

无效的

+ +
'abc'.repeat(Infinity); // RangeError
+'a'.repeat(2**28);      // RangeError
+
+ +

有效的

+ +
'abc'.repeat(0);    // ''
+'abc'.repeat(1);    // 'abc'
+'abc'.repeat(2);    // 'abcabc'
+'abc'.repeat(3.5);  // 'abcabcabc' (count will be converted to integer)
+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/stmt_after_return/index.html b/files/zh-cn/web/javascript/reference/errors/stmt_after_return/index.html new file mode 100644 index 0000000000..54fb1cf7a3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/stmt_after_return/index.html @@ -0,0 +1,76 @@ +--- +title: 'Warning: unreachable code after return statement' +slug: Web/JavaScript/Reference/Errors/Stmt_after_return +tags: + - 警告 +translation_of: Web/JavaScript/Reference/Errors/Stmt_after_return +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
Warning: unreachable code after return statement (Firefox)
+
+ +

错误类型

+ +

警告

+ +

什么地方出错了?

+ +

return语句之后的不可达的语句会在下列情形中产生:

+ + + +

当一个表达式出现在一个有效的 return 表达式之后时,会出现这个警告,用以说明在 return 语句之后的表达式不可达,即这条语句之后的表达式永远不会运行。

+ +

为什么我需要在 return 语句之后添加分号?在省略分号的 return 语句之后,开发者想要终止当前函数的执行还是返回return之后表达式的结果的意图是不明确的。这个警告表明这种情况下 return 语句的表述具有二义性。

+ +

当在省略分号的return语句之后出现下列语句时,不会出现警告:

+ + + +

示例

+ +

无效的例子

+ +
function f() {
+  var x = 3;
+  x += 4;
+  return x;   // return 语句立即退出当前方法
+  x -= 3;     // 因而该语句从不会执行,即该语句为不可达语句
+}
+
+function f() {
+  return     // 这条语句被视作 `return;`
+    3 + 4;   // 因而此处该函数已经返回,该语句永不会执行
+}
+
+ +

合适的例子

+ +
function f() {
+  var x = 3;
+  x += 4;
+  x -= 3;
+  return x;  // OK: 执行完成所有语句之后返回
+}
+
+function f() {
+  return 3 + 4  // OK: 省略分号的 return 语句与执行的表达式在同一行
+}
+
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/strict_non_simple_params/index.html b/files/zh-cn/web/javascript/reference/errors/strict_non_simple_params/index.html new file mode 100644 index 0000000000..3059705d88 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/strict_non_simple_params/index.html @@ -0,0 +1,113 @@ +--- +title: 'SyntaxError: "use strict" not allowed in function with non-simple parameters' +slug: Web/JavaScript/Reference/Errors/Strict_Non_Simple_Params +tags: + - Errors + - JavaScript + - SyntaxError + - TypeError + - use strict +translation_of: Web/JavaScript/Reference/Errors/Strict_Non_Simple_Params +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
Firefox:
+句法错误: "use strict" 不允许在带默认参数的函数中
+句法错误: "use strict" 不允许在带rest参数的函数中
+句法错误: "use strict" 不允许在带解构参数的函数中
+
+Chrome:
+句法错误: 非法的'use strict'指令,在带有非简单参数列表的函数中
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}.

+ +

哪里出错了?

+ +

在函数顶部直接写了 "use strict" ,而该函数拥有以下的参数其中之一:

+ + + +

根据ECMAScript规范,不允许在这些函数的顶部使用“use strict”指令。

+ +

示例

+ +

函数语句

+ +

在这种情况下,函数sum具有默认参数a = 1和b = 2:

+ +
function sum(a=1, b=2) {
+  // SyntaxError: "use strict" not allowed in function with default parameter
+  "use strict";
+  return a + b;
+}
+
+ +

如果这个函数应该处于 strict mode,并且整个脚本或封装函数也可以在严格模式下,可以移动 "use strict" 指令到函数之外:

+ +
"use strict";
+function sum(a=1, b=2) {
+  return a + b;
+}
+
+ +

函数表达式

+ +

函数表达式可以使用另一种解决方法:

+ +
var sum = function sum([a, b]) {
+  // SyntaxError: "use strict" not allowed in function with destructuring parameter
+  "use strict";
+  return a + b;
+};
+
+ +

这可以转换为以下表达式:

+ +
var sum = (function() {
+  "use strict";
+  return function sum([a, b]) {
+    return a + b;
+  };
+})();
+
+ +

箭头函数

+ +

如果箭头函数需要访问 this,则可以将箭头函数作为封闭函数来使用:

+ +
var callback = (...args) => {
+  // SyntaxError: "use strict" not allowed in function with rest parameter
+  "use strict";
+  return this.run(args);
+};
+
+ +

这可以转换为以下表达式:

+ +
var callback = (() => {
+  "use strict";
+  return (...args) => {
+    return this.run(args);
+  };
+})();
+
+ +

也可以看看

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/too_much_recursion/index.html b/files/zh-cn/web/javascript/reference/errors/too_much_recursion/index.html new file mode 100644 index 0000000000..1671a5598a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/too_much_recursion/index.html @@ -0,0 +1,54 @@ +--- +title: 'InternalError: too much recursion' +slug: Web/JavaScript/Reference/Errors/Too_much_recursion +tags: + - InternalError + - recursion + - 内部错误 +translation_of: Web/JavaScript/Reference/Errors/Too_much_recursion +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
InternalError: too much recursion
+
+ +

错误类型

+ +

{{jsxref("InternalError","内部错误")}}.

+ +

什么地方出错了?

+ +

一个调用自身的函数被称作递归函数。一些情况下,递归函数类似于一个循环,都重复地执行一个代码段许多次,都需要一个条件(用于避免无尽循环或此处的无尽递归)。当出现过于深层的递归或无尽递归时,JavaScript将会抛出此错误。

+ +

示例

+ +

根据递归终止的条件,该函数将递归地执行 10 次。

+ +
function loop(x) {
+  if (x >= 10) // "x >= 10" 是递归终止条件
+    return;
+  // 进行一些操作...
+  loop(x + 1); // 递归调用
+}
+loop(0);
+ +

将递归条件设置为一个极大的数值,将不能运行:

+ +
function loop(x) {
+  if (x >= 1000000000000)
+    return;
+  // 进行一些操作...
+  loop(x + 1);
+}
+loop(0);
+
+// InternalError: too much recursion
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/typed_array_invalid_arguments/index.html b/files/zh-cn/web/javascript/reference/errors/typed_array_invalid_arguments/index.html new file mode 100644 index 0000000000..314a4a425c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/typed_array_invalid_arguments/index.html @@ -0,0 +1,76 @@ +--- +title: 'TypeError: invalid arguments' +slug: Web/JavaScript/Reference/Errors/Typed_array_invalid_arguments +tags: + - JavaScript + - 类型错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Typed_array_invalid_arguments +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
TypeError: invalid arguments (Firefox)
+ +

错误类型

+ +

{{jsxref("TypeError")}}

+ +

哪里出错了?

+ +

类型化数组(Typed array) 的构造器可以通过接收以下类型的参数中的一种

+ + + +

来创建一个新的类型化数组。其他类型的构造器参数都无法创建合法的类型化数组。

+ +

示例

+ +

类型化数组——例如  {{jsxref("Uint8Array")}} ——无法通过字符串创建。实际上,字符串根本不能出现在类型化数组中。

+ +
var ta = new Uint8Array("nope");
+// TypeError: invalid arguments
+
+ +

创建一个合法的 {{jsxref("Uint8Array")}} 对象的不同方式:

+ +
// From a length
+var uint8 = new Uint8Array(2);
+uint8[0] = 42;
+console.log(uint8[0]); // 42
+console.log(uint8.length); // 2
+console.log(uint8.BYTES_PER_ELEMENT); // 1
+
+// From an array
+var arr = new Uint8Array([21,31]);
+console.log(arr[1]); // 31
+
+// From another TypedArray
+var x = new Uint8Array([21, 31]);
+var y = new Uint8Array(x);
+console.log(y[0]); // 21
+
+// From an ArrayBuffer
+var buffer = new ArrayBuffer(8);
+var z = new Uint8Array(buffer, 1, 4);
+
+// From an iterable
+var iterable = function*(){ yield* [1,2,3]; }();
+var uint8 = new Uint8Array(iterable);
+// Uint8Array[1, 2, 3]
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/undeclared_var/index.html b/files/zh-cn/web/javascript/reference/errors/undeclared_var/index.html new file mode 100644 index 0000000000..507da98563 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/undeclared_var/index.html @@ -0,0 +1,68 @@ +--- +title: 'ReferenceError: assignment to undeclared variable "x"' +slug: Web/JavaScript/Reference/Errors/Undeclared_var +tags: + - Errors + - JavaScript + - ReferenceError + - 严格模式 + - 错误 +translation_of: Web/JavaScript/Reference/Errors/Undeclared_var +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
ReferenceError: assignment to undeclared variable "x" (Firefox)
+ReferenceError: "x" is not defined (Chrome)
+ReferenceError: Variable undefined in strict mode (Edge)
+
+ +

错误类型

+ +

  仅在严格模式中出现 {{jsxref("ReferenceError")}} 警告。

+ +

发生了什么?

+ +

在代码里赋值了一个未声明的变量。换句话说,有处没有带着 var 关键字的赋值。事实上已声明的和未声明的变量之间有一些差异,这可能会导致意想不到的结果,这就是为什么 JavaScript 在严格模式打印出这种错误。

+ +

关于已声明和未声明的变量,其有三个注意事项:

+ + + +

更多信息及例子,请参考 var 页面。

+ +

关于未声明变量的赋值的错误仅在严格模式里出现。在非严格模式中,这些将被忽略。

+ +

示例

+ +

无效的

+ +

在本例中,"bar" 是未声明的变量。

+ +
function foo() {
+  "use strict";
+  bar = true;
+}
+foo(); // ReferenceError: assignment to undeclared variable bar
+
+ +

有效的

+ +

为了使 "bar" 是一个已声明变量,你需要在其前面加一个 var 关键字。

+ +
function foo() {
+  "use strict";
+  var bar = true;
+}
+foo();
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/undefined_prop/index.html b/files/zh-cn/web/javascript/reference/errors/undefined_prop/index.html new file mode 100644 index 0000000000..9cda2d0501 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/undefined_prop/index.html @@ -0,0 +1,64 @@ +--- +title: 'ReferenceError: reference to undefined property "x"' +slug: Web/JavaScript/Reference/Errors/Undefined_prop +tags: + - Errors + - JavaScript + - ReferenceError + - Strict Mode + - 严格模式 +translation_of: Web/JavaScript/Reference/Errors/Undefined_prop +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
ReferenceError: reference to undefined property "x" (Firefox)
+
+ +

错误类型

+ +

仅在 strict mode 下出现 {{jsxref("ReferenceError")}} 警告。

+ +

哪里出错了?

+ +

脚本尝试去访问一个不存在的对象属性。property accessors 页面描述了两种访问属性的方法。

+ +

引用未定义属性的错误仅出现在 strict mode 代码中。在非严格代码中,对不存在的属性的访问将被忽略。

+ +

示例

+ +

无效的

+ +

本例中,bar 属性是未定义的,隐藏 ReferenceError 会出现。

+ +
"use strict";
+
+var foo = {};
+foo.bar; // ReferenceError: reference to undefined property "bar"
+
+ +

无效的

+ +

为了避免错误,您需要向对象添加 bar 的定义或在尝试访问 bar 属性之前检查 bar 属性的存在;一种检查的方式是使用 {{jsxref("Object.prototype.hasOwnProperty()")}} 方法。如下所示:

+ +
"use strict";
+
+var foo = {};
+
+// Define the bar property
+
+foo.bar = "moon";
+console.log(foo.bar); // "moon"
+
+// Test to be sure bar exists before accessing it
+
+if (foo.hasOwnProperty("bar") {
+  console.log(foo.bar);
+}
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/unexpected_token/index.html b/files/zh-cn/web/javascript/reference/errors/unexpected_token/index.html new file mode 100644 index 0000000000..3de534c36a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/unexpected_token/index.html @@ -0,0 +1,50 @@ +--- +title: 'SyntaxError: Unexpected token' +slug: Web/JavaScript/Reference/Errors/Unexpected_token +tags: + - Errors + - JavaScript + - SyntaxError +translation_of: Web/JavaScript/Reference/Errors/Unexpected_token +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
SyntaxError: expected expression, got "x"
+SyntaxError: expected property name, got "x"
+SyntaxError: expected target, got "x"
+SyntaxError: expected rest argument name, got "x"
+SyntaxError: expected closing parenthesis, got "x"
+SyntaxError: expected '=>' after argument list, got "x"
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

期望获得一个特定的语法结构,但得到了其他的。 可能只是一个简单的错字。

+ +

示例

+ +

期望的表达式

+ +

例如,在调用函数时,不允许使用尾随逗号。 有尾逗号的时候,JavaScript 会期望有另一个参数,可以是任何表达式。

+ +
Math.max(2, 42,);
+// SyntaxError: expected expression, got ')'
+
+ +

正确的方法是省略最后一个逗号或添加另一个参数:

+ +
Math.max(2, 42);
+Math.max(2, 42, 13+37);
+
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/unexpected_type/index.html b/files/zh-cn/web/javascript/reference/errors/unexpected_type/index.html new file mode 100644 index 0000000000..c90cb20c27 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/unexpected_type/index.html @@ -0,0 +1,65 @@ +--- +title: 'TypeError: "x" is (not) "y"' +slug: Web/JavaScript/Reference/Errors/Unexpected_type +tags: + - 类型错误 +translation_of: Web/JavaScript/Reference/Errors/Unexpected_type +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
TypeError: "x" is (not) "y"
+
+Examples:
+TypeError: "x" is undefined
+TypeError: "x" is null
+TypeError: "undefined" is not an object
+TypeError: "x" is not an object or null
+TypeError: "x" is not a symbol
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}.

+ +

什么地方出错了?

+ +

出现了与期望不符的类型。 这个错误常常由 {{jsxref("undefined")}} 或 {{jsxref("null")}} 值引起。

+ +

此外,某些方法,例如 {{jsxref("Object.create()")}} 或 {{jsxref("Symbol.keyFor()")}}, 要求必须提供特定类型的参数。

+ +

示例

+ +

错误情形

+ +
// undefined and null cases on which the substring method won't work
+var foo = undefined;
+foo.substring(1); // TypeError: foo is undefined
+
+var foo = null;
+foo.substring(1); // TypeError: foo is null
+
+
+// Certain methods might require a specific type
+var foo = {}
+Symbol.keyFor(foo); // TypeError: foo is not a symbol
+
+var foo = 'bar'
+Object.create(foo); // TypeError: "foo" is not an object or null
+
+ +

解决方法

+ +

要解决空指针以及 undefinednull 值的问题, 你可以使用 typeof 操作符, 例如:

+ +
if (typeof foo !== 'undefined') {
+  // Now we know that foo is defined, we are good to go.
+}
+ +

相关页面

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/unnamed_function_statement/index.html b/files/zh-cn/web/javascript/reference/errors/unnamed_function_statement/index.html new file mode 100644 index 0000000000..83d147aaab --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/unnamed_function_statement/index.html @@ -0,0 +1,114 @@ +--- +title: 'SyntaxError: function statement requires a name' +slug: Web/JavaScript/Reference/Errors/Unnamed_function_statement +tags: + - JavaScript + - 语法错误 + - 错误提示 +translation_of: Web/JavaScript/Reference/Errors/Unnamed_function_statement +--- +
{{jsSidebar("Errors")}}
+ +

错误提示

+ +
SyntaxError: function statement requires a name [Firefox]
+SyntaxError: Unexpected token ( [Chrome]
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}}

+ +

哪里出错了?

+ +

函数声明需要提供函数名称。你需要检查函数是如何定义的,是否需要为其提供名称,出现问题的函数是否需要声明为函数表达式或立即调用函数表达式({{Glossary("IIFE")}}),以及函数在上下文环境中出现的位置是否正确。

+ +

示例

+ +

语句与表达式

+ +

函数语句(或函数声明)需要命名,以下写法是不正确的:

+ +
function () {
+  return 'Hello world';
+}
+// SyntaxError: function statement requires a name
+
+ +

你可以使用函数表达式(赋值)来代替:

+ +
var greet = function() {
+  return 'Hello world';
+};
+ +

者是你想将其作为立即调用函数表达式(IIFE,Immediately Invoked Function Expression),也就是定义后立即执行的函数。在这种情况下你需要用到更多的括号:

+ +
(function () {
+
+})();
+ +

标号函数(Labeled functions)

+ +

你使用函数标号(labels)的时候, 也需要在关键词 function 后面提供一个函数名称. 这样的代码是不能运行的:

+ +
function Greeter() {
+  german: function () {
+    return "Moin";
+  }
+}
+// SyntaxError: function statement requires a name
+
+ +

这个例子可以正常运行:

+ +
function Greeter() {
+  german: function g() {
+    return "Moin";
+  }
+}
+ +

对象方法

+ +

如果你想创建创建一个对象方法,那么需要首先创建一个对象。以下语法(function 关键字后面没有提供名称)是合法的:

+ +
var greeter = {
+  german: function () {
+    return "Moin";
+  }
+};
+ +

回调函数的语法

+ +

另外,如果使用到了回调函数,那么检查一下语法是否正确。大括号与逗号很容易使情况变糟。

+ +
promise.then(
+  function() {
+    console.log("success");
+  });
+  function() {
+    console.log("error");
+}
+// SyntaxError: function statement requires a name
+
+ +

正确的形式应该是这样的:

+ +
promise.then(
+  function() {
+    console.log("success");
+  },
+  function() {
+    console.log("error");
+  }
+);
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/unterminated_string_literal/index.html b/files/zh-cn/web/javascript/reference/errors/unterminated_string_literal/index.html new file mode 100644 index 0000000000..b0ab684413 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/unterminated_string_literal/index.html @@ -0,0 +1,67 @@ +--- +title: 'SyntaxError: unterminated string literal' +slug: Web/JavaScript/Reference/Errors/Unterminated_string_literal +tags: + - Error + - JavaScript + - SyntaxError +translation_of: Web/JavaScript/Reference/Errors/Unterminated_string_literal +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
SyntaxError: unterminated string literal
+
+ +

错误类型

+ +

{{jsxref("SyntaxError")}} 

+ +

哪里出错了?

+ +

某处 js 解析字符串出错。字符串必须使用单引号或双引号来正确的关闭。在 Javascript 中使用单引号的字符和双引号的字符串是没有区别的。字符串用转义字符不是单引号就是双引。为解决这个错误,检查一下:

+ + + +

示例

+ +

多行字符串

+ +

在javascript中你不能够直接使用多行字符串赋值给一个变量。如下:

+ +
var longString = "This is a very long string which needs
+                  to wrap across multiple lines because
+                  otherwise my code is unreadable.";
+// SyntaxError: unterminated string literal
+ +

可以使用"+"运算符,反斜杠,或模板字符串来代替多行。“+”运算符的使用如下:

+ +
var longString = "This is a very long string which needs " +
+                 "to wrap across multiple lines because " +
+                 "otherwise my code is unreadable.";
+
+ +

或者你可以使用“\”在每一行的末尾,以表示该字符串在下一行继续。要确保“\“之后没有没有空格和任何其他的字符,及缩进,否则该“\”将不会起作用。使用方法如下:

+ +
var longString = "This is a very long string which needs \
+to wrap across multiple lines because \
+otherwise my code is unreadable.";
+
+ +

另一种方式是使用 ES 2015 的环境所支持模板字符串(反引号` `)。

+ +
var longString = `This is a very long string which needs
+                  to wrap across multiple lines because
+                  otherwise my code is unreadable.`;
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/var_hides_argument/index.html b/files/zh-cn/web/javascript/reference/errors/var_hides_argument/index.html new file mode 100644 index 0000000000..01aa0260fe --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/var_hides_argument/index.html @@ -0,0 +1,51 @@ +--- +title: 'TypeError: variable "x" redeclares argument' +slug: Web/JavaScript/Reference/Errors/Var_hides_argument +translation_of: Web/JavaScript/Reference/Errors/Var_hides_argument +--- +
{{jsSidebar("Errors")}}
+ +

消息

+ +
TypeError: variable "x" redeclares argument (Firefox)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}} 警告仅仅在 严格模式下 出现。

+ +

哪里有问题?

+ +

函数参数中出现了名称相同的变量,之后在函数体中使用 var 赋值语句重新声明。 这可能是一个命名冲突,所以 JavaScript 警告了它。

+ +

这个错误只在 严格模式的代码 中作为警告出现。在非严格模式的代码中,重新声明会被忽略。

+ +

示例

+ +

无效情况

+ +

这个例子中,变量 arg 重新声明了参数。

+ +
"use strict";
+
+function f(arg) {
+  var arg = "foo";
+}
+
+ +

无效情况

+ +

为了修复警告,var 语句应该被移除,因为变量已经存在。或者,你可以重命名函数参数或者变量名称。

+ +
"use strict";
+
+function f(arg) {
+  arg = "foo";
+}
+
+ +

另见

+ + diff --git "a/files/zh-cn/web/javascript/reference/errors/\344\270\215\350\203\275\346\267\273\345\212\240\345\261\236\346\200\247/index.html" "b/files/zh-cn/web/javascript/reference/errors/\344\270\215\350\203\275\346\267\273\345\212\240\345\261\236\346\200\247/index.html" new file mode 100644 index 0000000000..cceeb330c4 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/errors/\344\270\215\350\203\275\346\267\273\345\212\240\345\261\236\346\200\247/index.html" @@ -0,0 +1,52 @@ +--- +title: 'TypeError: can''t assign to property "x" on "y": not an object' +slug: Web/JavaScript/Reference/Errors/不能添加属性 +translation_of: Web/JavaScript/Reference/Errors/Cant_assign_to_property +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
TypeError: can't assign to property "x" on {y}: not an object (Firefox)
+TypeError: Cannot create property 'x' on {y} (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}.

+ +

原因

+ +

在 {{jsxref("Strict_mode")}}下, 当试图给一个{{Glossary("symbol")}},{{Glossary("string")}},{{Glossary("number")}}或者一个{{Glossary("boolean")}}类型的数据创建一个属性时就会报 {{jsxref("TypeError")}}, 任何 {{Glossary("Primitive")}} 值都不允许有{{Glossary("property/JavaScript", "property")}}.

+ +

这个问题可能是由一个错误的值被放在了一个错误的地方导致的, 或者预期{{jsxref("String")}}或{{jsxref("Number")}}的对象变体

+ +

 

+ +

示例

+ +

错误的情况

+ +
'use strict';
+
+var foo = "my string";
+// 下面这行代码在非严格模式下不会执行.
+foo.bar = {}; // TypeError: can't assign to property "bar" on "my string": not an object
+
+ +

如何正确使用

+ +

有两种方式, 第一种修复这部分代码阻止{{Glossary("primitive")}}被用于这种情况, 或者可以通过使用对象构造器创建来修复.

+ +
'use strict';
+
+var foo = new String("my string");
+foo.bar = {};
+
+ +

页面相关

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/arguments/@@iterator/index.html b/files/zh-cn/web/javascript/reference/functions/arguments/@@iterator/index.html new file mode 100644 index 0000000000..5da702bb2b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/arguments/@@iterator/index.html @@ -0,0 +1,72 @@ +--- +title: 'arguments[@@iterator]()' +slug: Web/JavaScript/Reference/Functions/arguments/@@iterator +translation_of: Web/JavaScript/Reference/Functions/arguments/@@iterator +--- +
{{jsSidebar("Functions")}}
+ +

@@iterator 属性的初始值是和 {{jsxref("Array.prototype.values")}} 属性的初始值相同的对象。

+ +

语法

+ +
arguments[Symbol.iterator]()
+ +

实例

+ +

使用for...of循环的迭代

+ +
function f() {
+  // 你的浏览器必须支持 for..of 循环
+  // 以及 for 循环中的 let 区域变量
+  for (let letter of arguments) {
+    console.log(letter);
+  }
+}
+f('w', 'y', 'k', 'o', 'p');
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES6', '#sec-createunmappedargumentsobject', ' CreateUnmappedArgumentsObject')}}{{Spec2('ES6')}}初始定义.
{{SpecName('ES6', '#sec-createmappedargumentsobject', ' CreateMappedArgumentsObject')}}{{Spec2('ES6')}}初始定义.
{{SpecName('ESDraft', '#sec-createunmappedargumentsobject', 'CreateUnmappedArgumentsObject')}}{{Spec2('ESDraft')}} 
{{SpecName('ESDraft', '#sec-createmappedargumentsobject', 'CreateMappedArgumentsObject')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.functions.arguments.@@iterator")}}

+
+ +

更多

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/arguments/callee/index.html b/files/zh-cn/web/javascript/reference/functions/arguments/callee/index.html new file mode 100644 index 0000000000..c4682f0885 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/arguments/callee/index.html @@ -0,0 +1,177 @@ +--- +title: arguments.callee +slug: Web/JavaScript/Reference/Functions/arguments/callee +tags: + - Deprecated + - JavaScript + - arguments + - arguments.callee + - 函数 + - 属性 + - 已弃用 +translation_of: Web/JavaScript/Reference/Functions/arguments/callee +--- +
{{jsSidebar("Functions")}}
+ +

arguments.callee 属性包含当前正在执行的函数。

+ +

描述

+ +

callee 是 arguments 对象的一个属性。它可以用于引用该函数的函数体内当前正在执行的函数。这在函数的名称是未知时很有用,例如在没有名称的函数表达式 (也称为“匿名函数”)内。

+ +
警告:严格模式下,第5版 ECMAScript (ES5) 禁止使用 arguments.callee()。当一个函数必须调用自身的时候, 避免使用 arguments.callee(), 通过要么给函数表达式一个名字,要么使用一个函数声明.
+ +

为什么 arguments.callee 从ES5严格模式中删除了?

+ +

(改编自 a Stack Overflow answer by olliej)

+ +

早期版本的 JavaScript不允许使用命名函数表达式,出于这样的原因, 你不能创建一个递归函数表达式。

+ +

例如,下边这个语法就是行的通的:

+ +
function factorial (n) {
+    return !(n > 1) ? 1 : factorial(n - 1) * n;
+}
+
+[1,2,3,4,5].map(factorial);
+ +

但是:

+ +
[1,2,3,4,5].map(function (n) {
+    return !(n > 1) ? 1 : /* what goes here? */ (n - 1) * n;
+});
+ +

这个不行。为了解决这个问题, arguments.callee 添加进来了。然后你可以这么做

+ +
[1,2,3,4,5].map(function (n) {
+    return !(n > 1) ? 1 : arguments.callee(n - 1) * n;
+});
+ +

然而,这实际上是一个非常糟糕的解决方案,因为这 (以及其它的 arguments, callee, 和 caller 问题) 使得在通常的情况(你可以通过调试一些个别例子去实现它,但即使最好的代码也是次优选项,因为(JavaScript 解释器)做了不必要的检查)不可能实现内联和尾递归。另外一个主要原因是递归调用会获取到一个不同的 this 值,例如:

+ +
var global = this;
+
+var sillyFunction = function (recursed) {
+    if (!recursed) { return arguments.callee(true); }
+    if (this !== global) {
+        alert("This is: " + this);
+    } else {
+        alert("This is the global");
+    }
+}
+
+sillyFunction();
+ +

ECMAScript 3 通过允许命名函数表达式解决这些问题。例如:

+ +
[1,2,3,4,5].map(function factorial (n) {
+    return !(n > 1) ? 1 : factorial(n-1)*n;
+});
+ +

这有很多好处:

+ + + +

另外一个被废弃的特性是 arguments.callee.caller,具体点说则是 Function.caller。为什么? 额,在任何一个时间点,你能在堆栈中找到任何函数的最深层的调用者,也正如我在上面提到的,在调用堆栈有一个单一重大影响:不可能做大量的优化,或者有更多更多的困难。比如,如果你不能保证一个函数 f 不会调用一个未知函数,它就绝不可能是内联函数 f。基本上这意味着内联代码中积累了大量防卫代码:

+ +
function f (a, b, c, d, e) { return a ? b * c : d * e; }
+ +

如果 JavaScript 解释器不能保证所有提供的参数数量在被调用的时候都存在,那么它需要在行内代码插入检查,或者不能内联这个函数。现在在这个特殊例子里一个智能的解释器应该能重排检查而更优,并检查任何将不用到的值。然而在许多的情况里那是不可能的,也因此它不能够内联。 

+ +

例子

+ +

在匿名递归函数中使用 arguments.callee

+ +

递归函数必须能够引用它本身。很典型的,函数通过自己的名字调用自己。然而,匿名函数 (通过 函数表达式 或者 函数构造器 创建) 没有名称。因此如果没有可访问的变量指向该函数,唯一能引用它的方式就是通过 arguments.callee

+ +

下面的例子定义了一个函数,按流程,定义并返回了一个阶乘函数。该例并不是很实用,并且几乎都能够用 命名函数表达式 实现同样结果的例子, and there are nearly no cases where the same result cannot be achieved with .

+ +
function create() {
+   return function(n) {
+      if (n <= 1)
+         return 1;
+      return n * arguments.callee(n - 1);
+   };
+}
+
+var result = create()(5); // returns 120 (5 * 4 * 3 * 2 * 1)
+
+ +

没有替代方案的 arguments.callee

+ +

当你必须要使用Function构造函数时,下面的例子是没有可以替代 arguments.callee 的方案的,因此弃用它时会产生一个BUG (参看 {{Bug("725398")}}):

+ +
function createPerson (sIdentity) {
+    var oPerson = new Function("alert(arguments.callee.identity);");
+    oPerson.identity = sIdentity;
+    return oPerson;
+}
+
+var john = createPerson("John Smith");
+
+john();
+ +

译者注:利用命名函数表达式也可以实现上述例子的同样效果

+ +
function createPerson (identity) {
+    function Person() {
+        console.log(Person.identity);
+    }
+    Person.identity = identity;
+    return Person;
+}
+var john = createPerson("John Smith");
+
+john(); //John Smith
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.2
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}} 
+  
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.functions.arguments.callee")}}

+ +

也可以看看

+ + + +

 

diff --git a/files/zh-cn/web/javascript/reference/functions/arguments/caller/index.html b/files/zh-cn/web/javascript/reference/functions/arguments/caller/index.html new file mode 100644 index 0000000000..13128ec962 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/arguments/caller/index.html @@ -0,0 +1,47 @@ +--- +title: caller +slug: Web/JavaScript/Reference/Functions/arguments/caller +translation_of: Archive/Web/JavaScript/arguments.caller +--- +

{{jsSidebar("Functions")}}

+ +

废弃的 arguments.caller 属性原先用在函数执行的时候调用自身。本属性已被移除且不再有用。

+ +

描述

+ +

arguments.caller 已经不可使用了,但是你还可以使用 {{jsxref("Function.caller")}}。

+ +
function whoCalled() {
+   if (whoCalled.caller == null)
+      console.log('I was called from the global scope.');
+   else
+      console.log(whoCalled.caller + ' called me!');
+}
+
+ +

示例

+ +

下例演示了arguments.caller属性的作用.

+ +
function whoCalled() {
+   if (arguments.caller == null)
+      console.log('该函数在全局作用域内被调用.');
+   else
+      console.log(arguments.caller + '调用了我!');
+}
+ +

规范

+ +

无相关标准。JavaScript 1.1 实现,{{bug(7224)}} 移除 caller,因为潜在的不安全性。

+ +

浏览器支持

+ + + +

{{Compat("javascript.functions.arguments.caller")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/arguments/index.html b/files/zh-cn/web/javascript/reference/functions/arguments/index.html new file mode 100644 index 0000000000..f1f356a935 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/arguments/index.html @@ -0,0 +1,275 @@ +--- +title: Arguments 对象 +slug: Web/JavaScript/Reference/Functions/arguments +tags: + - Functions + - JavaScript + - Reference + - arguments + - arguments.length +translation_of: Web/JavaScript/Reference/Functions/arguments +--- +
+
+
{{jsSidebar("Functions")}}
+
+
+ +

arguments 是一个对应于传递给函数的参数的类数组对象。

+ +

{{EmbedInteractiveExample("pages/js/functions-arguments.html")}}

+ + + +

描述

+ +
+

Note: If you're writing ES6 compatible code, then rest parameters should be preferred.

+
+ +
+

Note: “Array-like” means that arguments has a {{jsxref("Functions/arguments/length", "length")}} property and properties indexed from zero, but it doesn't have {{JSxRef("Array")}}'s built-in methods like {{jsxref("Array.forEach", "forEach()")}} and {{jsxref("Array.map", "map()")}}. See §Description for details.

+
+ +

arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处。例如,如果一个函数传递了三个参数,你可以以如下方式引用他们:

+ +
arguments[0]
+arguments[1]
+arguments[2]
+
+ +

参数也可以被设置:

+ +
arguments[1] = 'new value';
+ +

arguments对象不是一个 {{jsxref("Array")}} 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。例如,它没有 pop 方法。但是它可以被转换为一个真正的Array

+ +
var args = Array.prototype.slice.call(arguments);
+var args = [].slice.call(arguments);
+
+// ES2015
+const args = Array.from(arguments);
+const args = [...arguments];
+
+ +
+

对参数使用slice会阻止某些JavaScript引擎中的优化 (比如 V8 - 更多信息)。如果你关心性能,尝试通过遍历arguments对象来构造一个新的数组。另一种方法是使用被忽视的Array构造函数作为一个函数:

+ +
var args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));
+
+
+ +

如果调用的参数多于正式声明接受的参数,则可以使用arguments对象。这种技术对于可以传递可变数量的参数的函数很有用。使用 arguments.length来确定传递给函数参数的个数,然后使用arguments对象来处理每个参数。要确定函数签名中(输入)参数的数量,请使用Function.length属性。

+ +

对参数使用 typeof

+ +

typeof参数返回 'object'。

+ +
console.log(typeof arguments);    // 'object'
+// arguments 对象只能在函数内使用
+function test(a){
+    console.log(a,Object.prototype.toString.call(arguments));
+    console.log(arguments[0],arguments[1]);
+    console.log(typeof arguments[0]);
+}
+test(1);
+/*
+1 "[object Arguments]"
+1 undefined
+number
+*/
+ +

可以使用索引确定单个参数的类型。

+ +
console.log(typeof arguments[0]); //this will return the typeof individual arguments.
+ +

对参数使用扩展语法

+ +

您还可以使用{{jsxref("Array.from()")}}方法或扩展运算符将参数转换为真实数组:

+ +
var args = Array.from(arguments);
+var args = [...arguments];
+ +

属性

+ +
+
arguments.callee
+
指向参数所属的当前执行的函数。
+
+ +
+
+

指向调用当前函数的函数。

+
+
arguments.length
+
传递给函数的参数数量。
+
arguments[@@iterator]
+
返回一个新的{{jsxref("Array/@@iterator", "Array 迭代器", "", 0)}} 对象,该对象包含参数中每个索引的值。
+
+
+ +
+

注意: 在严格模式下,arguments对象已与过往不同。arguments[@@iterator]不再与函数的实际形参之间共享,同时caller属性也被移除。

+
+ +

例子

+ +

遍历参数求和

+ +
function add() {
+    var sum =0,
+        len = arguments.length;
+    for(var i=0; i<len; i++){
+        sum += arguments[i];
+    }
+    return sum;
+}
+add()                           // 0
+add(1)                          // 1
+add(1,2,3,4);                   // 10
+ +

定义连接字符串的函数

+ +

这个例子定义了一个函数来连接字符串。这个函数唯一正式声明了的参数是一个字符串,该参数指定一个字符作为衔接点来连接字符串。该函数定义如下:

+ +
function myConcat(separator) {
+  var args = Array.prototype.slice.call(arguments, 1);
+  return args.join(separator);
+}
+ +

你可以传递任意数量的参数到该函数,并使用每个参数作为列表中的项创建列表。

+ +
// returns "red, orange, blue"
+myConcat(", ", "red", "orange", "blue");
+
+// returns "elephant; giraffe; lion; cheetah"
+myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
+
+// returns "sage. basil. oregano. pepper. parsley"
+myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
+ +

定义创建HTML列表的方法

+ +

这个例子定义了一个函数通过一个字符串来创建HTML列表。这个函数唯一正式声明了的参数是一个字符。当该参数为 "u" 时,创建一个无序列表 (项目列表);当该参数为 "o" 时,则创建一个有序列表 (编号列表)。该函数定义如下:

+ +
function list(type) {
+  var result = "<" + type + "l><li>";
+  var args = Array.prototype.slice.call(arguments, 1);
+  result += args.join("</li><li>");
+  result += "</li></" + type + "l>"; // end list
+
+  return result;
+}
+ +

你可以传递任意数量的参数到该函数,并将每个参数作为一个项添加到指定类型的列表中。例如:

+ +
var listHTML = list("u", "One", "Two", "Three");
+
+/* listHTML is:
+
+"<ul><li>One</li><li>Two</li><li>Three</li></ul>"
+
+*/
+
+ +

剩余参数、默认参数和解构赋值参数

+ +

arguments对象可以与剩余参数默认参数解构赋值参数结合使用。

+ +
function foo(...args) {
+  return args;
+}
+foo(1, 2, 3);  // [1,2,3]
+
+ +

在严格模式下,剩余参数默认参数解构赋值参数的存在不会改变 arguments对象的行为,但是在非严格模式下就有所不同了。

+ +

当非严格模式中的函数没有包含剩余参数默认参数解构赋值,那么arguments对象中的值跟踪参数的值(反之亦然)。看下面的代码:

+ +
function func(a) {
+  arguments[0] = 99;   // 更新了arguments[0] 同样更新了a
+  console.log(a);
+}
+func(10); // 99
+
+ +

并且

+ +
function func(a) {
+  a = 99;              // 更新了a 同样更新了arguments[0]
+  console.log(arguments[0]);
+}
+func(10); // 99
+
+ +

当非严格模式中的函数包含剩余参数默认参数解构赋值,那么arguments对象中的值不会跟踪参数的值(反之亦然)。相反, arguments反映了调用时提供的参数:

+ +
function func(a = 55) {
+  arguments[0] = 99; // updating arguments[0] does not also update a
+  console.log(a);
+}
+func(10); // 10
+ +

并且

+ +
function func(a = 55) {
+  a = 99; // updating a does not also update arguments[0]
+  console.log(arguments[0]);
+}
+func(10); // 10
+ +

并且

+ +
function func(a = 55) {
+  console.log(arguments[0]);
+}
+func(); // undefined
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}}
{{SpecName('ES2015', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES2015')}}
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.functions.arguments")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/arguments/length/index.html b/files/zh-cn/web/javascript/reference/functions/arguments/length/index.html new file mode 100644 index 0000000000..3bf25335f4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/arguments/length/index.html @@ -0,0 +1,75 @@ +--- +title: arguments.length +slug: Web/JavaScript/Reference/Functions/arguments/length +translation_of: Web/JavaScript/Reference/Functions/arguments/length +--- +
{{jsSidebar("Functions")}}
+ +

本次函数调用时传入函数的实参数量.

+ +

Syntax

+ +
arguments.length
+ +

描述

+ +

arguments.length表示的是实际上向函数传入了多少个参数,这个数字可以比形参数量大,也可以比形参数量小(形参数量的值可以通过Function.length获取到).

+ +

例子

+ +

例子: 使用arguments.length

+ +

这个例中,我们定义了一个可以相加任意个数字的函数.

+ +
function adder(base, /*, n2, ... */) {
+  base = Number(base);
+  for (var i = 0; i < arguments.length; i++) {
+    base += Number(arguments[i]);
+  }
+  return base;
+}
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.functions.arguments.length")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/arrow_functions/index.html b/files/zh-cn/web/javascript/reference/functions/arrow_functions/index.html new file mode 100644 index 0000000000..a7a50b8d5b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/arrow_functions/index.html @@ -0,0 +1,484 @@ +--- +title: 箭头函数 +slug: Web/JavaScript/Reference/Functions/Arrow_functions +tags: + - ECMAScript 2015 + - ES6 Arrow Function + - Functions + - Intermediate + - JavaScript + - Lambda + - Lambda Expression + - Reference + - ramda +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +
{{jsSidebar("Functions")}} 
+ +

箭头函数表达式的语法比函数表达式更简洁,并且没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

+ +{{EmbedInteractiveExample("pages/js/functions-arrow.html")}} + +

语法

+ +
+

基础语法

+ +
(param1, param2, …, paramN) => { statements }
+(param1, param2, …, paramN) => expression
+//相当于:(param1, param2, …, paramN) =>{ return expression; }
+
+// 当只有一个参数时,圆括号是可选的:
+(singleParam) => { statements }
+singleParam => { statements }
+
+// 没有参数的函数应该写成一对圆括号。
+() => { statements }
+
+ +

高级语法

+ +
+
//加括号的函数体返回对象字面量表达式:
+params => ({foo: bar})
+
+//支持剩余参数默认参数
+(param1, param2, ...rest) => { statements }
+(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
+statements }
+
+//同样支持参数列表解构
+let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
+f();  // 6
+
+ +

描述

+ +

参考 "ES6 In Depth: Arrow functions" on hacks.mozilla.org.

+ +

引入箭头函数有两个方面的作用:更简短的函数并且不绑定this

+ +

更短的函数

+ +
var elements = [
+  'Hydrogen',
+  'Helium',
+  'Lithium',
+  'Beryllium'
+];
+
+elements.map(function(element) {
+  return element.length;
+}); // 返回数组:[8, 6, 7, 9]
+
+// 上面的普通函数可以改写成如下的箭头函数
+elements.map((element) => {
+  return element.length;
+}); // [8, 6, 7, 9]
+
+// 当箭头函数只有一个参数时,可以省略参数的圆括号
+elements.map(element => {
+ return element.length;
+}); // [8, 6, 7, 9]
+
+// 当箭头函数的函数体只有一个 `return` 语句时,可以省略 `return` 关键字和方法体的花括号
+elements.map(element => element.length); // [8, 6, 7, 9]
+
+// 在这个例子中,因为我们只需要 `length` 属性,所以可以使用参数解构
+// 需要注意的是字符串 `"length"` 是我们想要获得的属性的名称,而 `lengthFooBArX` 则只是个变量名,
+// 可以替换成任意合法的变量名
+elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]
+
+ +

没有单独的this

+ +

在箭头函数出现之前,每一个新函数根据它是被如何调用的来定义这个函数的this值:

+ + + +

This被证明是令人厌烦的面向对象风格的编程。

+ +
function Person() {
+  // Person() 构造函数定义 `this`作为它自己的实例.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // 在非严格模式, growUp()函数定义 `this`作为全局对象,
+    // 与在 Person()构造函数中定义的 `this`并不相同.
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

在ECMAScript 3/5中,通过将this值分配给封闭的变量,可以解决this问题。

+ +
function Person() {
+  var that = this;
+  that.age = 0;
+
+  setInterval(function growUp() {
+    // 回调引用的是`that`变量, 其值是预期的对象.
+    that.age++;
+  }, 1000);
+}
+ +

或者,可以创建绑定函数,以便将预先分配的this值传递到绑定的目标函数(上述示例中的growUp()函数)。

+ +

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。因此,在下面的代码中,传递给setInterval的函数内的this与封闭函数中的this值相同:

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this| 正确地指向 p 实例
+  }, 1000);
+}
+
+var p = new Person();
+ +

与严格模式的关系

+ +

鉴于 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。

+ +
var f = () => { 'use strict'; return this; };
+f() === window; // 或者 global
+ +

严格模式的其他规则依然不变.

+ +

通过 call 或 apply 调用

+ +

由于 箭头函数没有自己的this指针,通过 call() 或 apply() 方法调用一个函数时,只能传递参数(不能绑定this---译者注),他们的第一个参数会被忽略。(这种现象对于bind方法同样成立---译者注)

+ +
var adder = {
+  base : 1,
+
+  add : function(a) {
+    var f = v => v + this.base;
+    return f(a);
+  },
+
+  addThruCall: function(a) {
+    var f = v => v + this.base;
+    var b = {
+      base : 2
+    };
+
+    return f.call(b, a);
+  }
+};
+
+console.log(adder.add(1));         // 输出 2
+console.log(adder.addThruCall(1)); // 仍然输出 2
+ +

不绑定arguments

+ +

箭头函数不绑定Arguments 对象。因此,在本示例中,arguments只是引用了封闭作用域内的arguments:

+ +
var arguments = [1, 2, 3];
+var arr = () => arguments[0];
+
+arr(); // 1
+
+function foo(n) {
+  var f = () => arguments[0] + n; // 隐式绑定 foo 函数的 arguments 对象. arguments[0] 是 n,即传给foo函数的第一个参数
+  return f();
+}
+
+foo(1); // 2
+foo(2); // 4
+foo(3); // 6
+foo(3,2);//6
+
+ +

在大多数情况下,使用剩余参数是相较使用arguments对象的更好选择。

+ +
function foo(arg) {
+  var f = (...args) => args[0];
+  return f(arg);
+}
+foo(1); // 1
+
+function foo(arg1,arg2) {
+    var f = (...args) => args[1];
+    return f(arg1,arg2);
+}
+foo(1,2);  //2
+
+
+ +

使用箭头函数作为方法

+ +

如上所述,箭头函数表达式对非方法函数是最合适的。让我们看看当我们试着把它们作为方法时发生了什么。

+ +
'use strict';
+var obj = {
+  i: 10,
+  b: () => console.log(this.i, this),
+  c: function() {
+    console.log( this.i, this)
+  }
+}
+obj.b();
+// undefined, Window{...}
+obj.c();
+// 10, Object {...}
+
+ +

箭头函数没有定义this绑定。另一个涉及{{jsxref("Object.defineProperty()")}}的示例:

+ +
'use strict';
+var obj = {
+  a: 10
+};
+
+Object.defineProperty(obj, "b", {
+  get: () => {
+    console.log(this.a, typeof this.a, this);
+    return this.a+10;
+   // 代表全局对象 'Window', 因此 'this.a' 返回 'undefined'
+  }
+});
+
+obj.b; // undefined   "undefined"   Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
+
+ +

使用 new 操作符

+ +

箭头函数不能用作构造器,和 new一起用会抛出错误。

+ +
var Foo = () => {};
+var foo = new Foo(); // TypeError: Foo is not a constructor
+ +

使用prototype属性

+ +

箭头函数没有prototype属性。

+ +
var Foo = () => {};
+console.log(Foo.prototype); // undefined
+ +

使用 yield 关键字

+ +

 yield 关键字通常不能在箭头函数中使用(除非是嵌套在允许使用的函数内)。因此,箭头函数不能用作函数生成器。

+ +

函数体

+ +

箭头函数可以有一个“简写体”或常见的“块体”。

+ +

在一个简写体中,只需要一个表达式,并附加一个隐式的返回值。在块体中,必须使用明确的return语句。

+ +
var func = x => x * x;
+// 简写函数 省略return
+
+var func = (x, y) => { return x + y; };
+//常规编写 明确的返回值
+ +

返回对象字面量

+ +

记住用params => {object:literal}这种简单的语法返回对象字面量是行不通的。

+ +
var func = () => { foo: 1 };
+// Calling func() returns undefined!
+
+var func = () => { foo: function() {} };
+// SyntaxError: function statement requires a name
+ +

这是因为花括号({} )里面的代码被解析为一系列语句(即 foo 被认为是一个标签,而非对象字面量的组成部分)。

+ +

所以,记得用圆括号把对象字面量包起来:

+ +
var func = () => ({foo: 1});
+ +

换行

+ +

箭头函数在参数和箭头之间不能换行。

+ +
var func = ()
+           => 1;
+// SyntaxError: expected expression, got '=>'
+ +

但是,可以通过在 ‘=>’ 之后换行,或者用 ‘( )’、'{ }'来实现换行,如下:

+ +
var func = (a, b, c) =>
+  1;
+
+var func = (a, b, c) => (
+  1
+);
+
+var func = (a, b, c) => {
+  return 1
+};
+
+var func = (
+  a,
+  b,
+  c
+) => 1;
+
+// 不会有语法错误
+ +

解析顺序

+ +

虽然箭头函数中的箭头不是运算符,但箭头函数具有与常规函数不同的特殊运算符优先级解析规则。

+ +
let callback;
+
+callback = callback || function() {}; // ok
+
+callback = callback || () => {};
+// SyntaxError: invalid arrow-function arguments
+
+callback = callback || (() => {});    // ok
+ +

更多示例

+ +
// 空的箭头函数返回 undefined
+let empty = () => {};
+
+(() => 'foobar')();
+// Returns "foobar"
+// (这是一个立即执行函数表达式,可参阅 'IIFE'术语表)
+
+
+var simple = a => a > 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) => a > b ? a : b;
+
+// Easy array filtering, mapping, ...
+
+var arr = [5, 6, 13, 0, 1, 18, 23];
+
+var sum = arr.reduce((a, b) => a + b);
+// 66
+
+var even = arr.filter(v => v % 2 == 0);
+// [6, 0, 18]
+
+var double = arr.map(v => v * 2);
+// [10, 12, 26, 0, 2, 36, 46]
+
+// 更简明的promise链
+promise.then(a => {
+  // ...
+}).then(b => {
+  // ...
+});
+
+// 无参数箭头函数在视觉上容易分析
+setTimeout( () => {
+  console.log('I happen sooner');
+  setTimeout( () => {
+    // deeper code
+    console.log('I happen later');
+  }, 1);
+}, 1);
+ +

箭头函数也可以使用条件(三元)运算符:

+ +
var simple = a => a > 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) => a > b ? a : b;
+ +
+

箭头函数内定义的变量及其作用域

+
+ +
// 常规写法
+var greeting = () => {let now = new Date(); return ("Good" + ((now.getHours() > 17) ? " evening." : " day."));}
+greeting();          //"Good day."
+console.log(now);    // ReferenceError: now is not defined 标准的let作用域
+
+// 参数括号内定义的变量是局部变量(默认参数)
+var greeting = (now=new Date()) => "Good" + (now.getHours() > 17 ? " evening." : " day.");
+greeting();          //"Good day."
+console.log(now);    // ReferenceError: now is not defined
+
+// 对比:函数体内{}不使用var定义的变量是全局变量
+var greeting = () => {now = new Date(); return ("Good" + ((now.getHours() > 17) ? " evening." : " day."));}
+greeting();           //"Good day."
+console.log(now);     // Fri Dec 22 2017 10:01:00 GMT+0800 (中国标准时间)
+
+// 对比:函数体内{} 用var定义的变量是局部变量
+var greeting = () => {var now = new Date(); return ("Good" + ((now.getHours() > 17) ? " evening." : " day."));}
+greeting(); //"Good day."
+console.log(now);    // ReferenceError: now is not defined
+
+ +
+

箭头函数也可以使用闭包:

+
+ +
// 标准的闭包函数
+function A(){
+      var i=0;
+      return function b(){
+              return (++i);
+      };
+};
+
+var v=A();
+v();    //1
+v();    //2
+
+
+//箭头函数体的闭包( i=0 是默认参数)
+var Add = (i=0) => {return (() => (++i) )};
+var v = Add();
+v();           //1
+v();           //2
+
+//因为仅有一个返回,return 及括号()也可以省略
+var Add = (i=0)=> ()=> (++i);
+
+
+ +
+

 箭头函数递归

+
+ +
var fact = (x) => ( x==0 ?  1 : x*fact(x-1) );
+fact(5);       // 120
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.functions.arrow_functions")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/default_parameters/index.html b/files/zh-cn/web/javascript/reference/functions/default_parameters/index.html new file mode 100644 index 0000000000..7422fc208b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/default_parameters/index.html @@ -0,0 +1,220 @@ +--- +title: 默认参数值 +slug: Web/JavaScript/Reference/Functions/Default_parameters +tags: + - ECMAScript 2015 + - Functions + - JavaScript +translation_of: Web/JavaScript/Reference/Functions/Default_parameters +--- +

{{jsSidebar("Functions")}}

+ +

函数默认参数允许在没有值或undefined被传入时使用默认形参。

+ +
{{EmbedInteractiveExample("pages/js/functions-default.html")}}
+ + + +

语法

+ +
function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
+    statements
+}
+
+ +

描述

+ +

JavaScript 中函数的参数默认是{{jsxref("undefined")}}。然而,在某些情况下可能需要设置一个不同的默认值。这是默认参数可以帮助的地方。

+ +

以前,一般设置默认参数的方法是在函数体测试参数是否为undefined,如果是的话就设置为默认的值。

+ +

下面的例子中,如果在调用multiply时,参数b的值没有提供,那么它的值就为undefined。如果直接执行a * b,函数会返回 NaN

+ +
function multiply(a, b) {
+  return a * b;
+}
+
+multiply(5, 2); // 10
+multiply(5);    // NaN !
+
+
+ +

为了防止这种情况,第二行代码解决了这个问题,其中如果只使用一个参数调用multiply,则b设置为1

+ +
function multiply(a, b) {
+  b = (typeof b !== 'undefined') ?  b : 1;
+  return a * b;
+}
+
+multiply(5, 2); // 10
+multiply(5);    // 5
+ +

有了默认参数,我们不需要再在函数体内做不必要的检查。现在你可以在函数头将b的默认值置为1

+ +
function multiply(a, b = 1) {
+  return a * b;
+}
+
+multiply(5, 2); // 10
+multiply(5);    // 5
+ +

示例

+ +

传入 undefined vs 其他假值

+ +

在第二次调用中,即使第一个参数在调用时显式设置为undefined(虽然不是null或其他falsy值),但是num参数的值是默认值。

+ +
function test(num = 1) {
+  console.log(typeof num);
+}
+
+test();          // 'number' (num is set to 1)
+test(undefined); // 'number' (num is set to 1 too)
+
+// test with other falsy values:
+test('');        // 'string' (num is set to '')
+test(null);      // 'object' (num is set to null)
+ +

调用时解析

+ +

在函数被调用时,参数默认值会被解析,所以不像Python中的例子,每次函数调用时都会创建一个新的参数对象。

+ +
function append(value, array = []) {
+  array.push(value);
+  return array;
+}
+
+append(1); //[1]
+append(2); //[2], not [1, 2]
+ +

这个规则对于函数和变量也是适用的。

+ +
function callSomething(thing = something()) {
+ return thing;
+}
+
+let numberOfTimesCalled = 0;
+function something() {
+  numberOfTimesCalled += 1;
+  return numberOfTimesCalled;
+}
+
+callSomething(); // 1
+callSomething(); // 2
+ +

默认参数可用于后面的默认参数

+ +

已经遇到的参数可用于以后的默认参数:

+ +
function greet(name, greeting, message = greeting + ' ' + name) {
+    return [name, greeting, message];
+}
+
+greet('David', 'Hi');  // ["David", "Hi", "Hi David"]
+greet('David', 'Hi', 'Happy Birthday!');  // ["David", "Hi", "Happy Birthday!"]
+
+ +

以下这个例子近似模拟了一些比较简单的情况,并说明了特殊情况是怎么被处理的。

+ +
function go() {
+  return ':P';
+}
+
+function withDefaults(a, b = 5, c = b, d = go(), e = this,
+                      f = arguments, g = this.value) {
+  return [a, b, c, d, e, f, g];
+}
+
+function withoutDefaults(a, b, c, d, e, f, g) {
+  switch (arguments.length) {
+    case 0:
+      a;
+    case 1:
+      b = 5;
+    case 2:
+      c = b;
+    case 3:
+      d = go();
+    case 4:
+      e = this;
+    case 5:
+      f = arguments;
+    case 6:
+      g = this.value;
+    default:
+  }
+  return [a, b, c, d, e, f, g];
+}
+
+withDefaults.call({value: '=^_^='});
+// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
+
+
+withoutDefaults.call({value: '=^_^='});
+// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
+ +

函数嵌套定义

+ +

在 Gecko 33 {{geckoRelease(33)}} 中引入。在函数体内的函数声明不能引用内部的默认参数,并且会在 SpiderMonkey 抛出一个{{jsxref("ReferenceError")}}(现在是 {{jsxref("TypeError")}}),参见 {{bug(1022967)}}。默认参数总是会被首先执行,而在函数体内部的函数声明会在之后生效。

+ +
// Doesn't work! Throws ReferenceError.
+function f(a = go()) {
+  function go() { return ':P'; }
+}
+ +

位于默认参数之后非默认参数

+ +

在Gecko 26 {{geckoRelease(26)}}之前,以下代码会造成{{jsxref("SyntaxError")}}错误。这已经在{{bug(1022967)}}中修复,并在以后的版本中按预期方式工作。参数仍然设置为从左到右,覆盖默认参数,即使后面的参数没有默认值。

+ +
function f(x = 1, y) {
+  return [x, y];
+}
+
+f(); // [1, undefined]
+f(2); // [2, undefined]
+ +

有默认值的解构参数

+ +

你可以通过解构赋值为参数赋值:

+ +
function f([x, y] = [1, 2], {z: z} = {z: 3}) {
+  return x + y + z;
+}
+
+f(); // 6
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.functions.default_parameters")}}

+ +

相关链接

+ + + +

 

diff --git a/files/zh-cn/web/javascript/reference/functions/get/index.html b/files/zh-cn/web/javascript/reference/functions/get/index.html new file mode 100644 index 0000000000..38c16fea77 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/get/index.html @@ -0,0 +1,175 @@ +--- +title: getter +slug: Web/JavaScript/Reference/Functions/get +tags: + - ECMAScript 2015 + - Functions + - JavaScript +translation_of: Web/JavaScript/Reference/Functions/get +--- +
{{jsSidebar("Functions")}}
+ +

get语法将对象属性绑定到查询该属性时将被调用的函数。

+ +
{{EmbedInteractiveExample("pages/js/functions-getter.html")}}
+ + + +

语法

+ +
{get prop() { ... } }
+
+{get [expression]() { ... } }
+ +

参数

+ +
+
prop
+
要绑定到给定函数的属性名。
+
expression
+
从 ECMAScript 2015 开始,还可以使用一个计算属性名的表达式绑定到给定的函数。
+
+ +

描述

+ +

有时需要允许访问返回动态计算值的属性,或者你可能需要反映内部变量的状态,而不需要使用显式方法调用。在JavaScript中,可以使用 getter 来实现。

+ +

尽管可以结合使用getter和setter来创建一个伪属性,但是不可能同时将一个 getter 绑定到一个属性并且该属性实际上具有一个值。

+ +

使用get语法时应注意以下问题:

+ +
+ +
+ +

示例

+ +

在新对象初始化时定义一个getter

+ +

这会为obj创建一个伪属性latest,它会返回log数组的最后一个元素。

+ +
const obj = {
+  log: ['example','test'],
+  get latest() {
+    if (this.log.length == 0) return undefined;
+    return this.log[this.log.length - 1];
+  }
+}
+console.log(obj.latest); // "test".
+ +

注意,尝试为latest分配一个值不会改变它。

+ +

使用delete操作符删除 getter

+ +

只需使用 delete,就可删除 getter:

+ +
delete obj.latest;
+
+ +

使用defineProperty在现有对象上定义 getter

+ +

要随时将 getter 添加到现有对象,使用 {{jsxref("Object.defineProperty()")}}.

+ +
var o = { a:0 }
+
+Object.defineProperty(o, "b", { get: function () { return this.a + 1; } });
+
+console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)
+ +

使用计算出的属性名

+ +
var expr = 'foo';
+
+var obj = {
+  get [expr]() { return 'bar'; }
+};
+
+console.log(obj.foo); // "bar"
+ +

智能 / 自我复写/ 懒加载 getters

+ +

Getters 给你一种方法来定义一个对象的属性,但是在访问它们之前不会计算属性的值。 getter 延迟计算值的成本,直到需要此值,如果不需要,您就不用支付成本。

+ +

一种额外的优化技术是用智能(或称记忆化)getters 延迟属性值的计算并将其缓存以备以后访问。该值是在第一次调用getter 时计算的,然后被缓存,因此后续访问返回缓存值而不重新计算它。这在以下情况下很有用:

+ + + +
+

这意味着你不应该为你希望更改其值的属性使用懒 getter,因为 getter 不会重新计算该值。

+
+ +

在以下示例中,对象具有一个 getter 属性。在获取属性时,该属性将从对象中删除并重新添加,但此时将隐式显示为数据属性。最后返回得到值。

+ +
get notifier() {
+  delete this.notifier;
+  return this.notifier = document.getElementById('bookmarked-notification-anchor');
+},
+
+ +

对于Firefox代码,另请参阅定义defineLazyGetter()函数的XPCOMUtils.jsm代码模块。

+ +

get vs. defineProperty

+ +

当使用 get 关键字时,它和{{jsxref("Object.defineProperty()")}} 有类似的效果,在{{jsxref("classes")}}中使用时,二者有细微的差别。

+ +

当使用 get 关键字时,属性将被定义在实例的原型上,当使用{{jsxref("Object.defineProperty()")}}时,属性将被定义在实例自身上。

+ +
class Example {
+  get hello() {
+    return 'world';
+  }
+}
+
+const obj = new Example();
+console.log(obj.hello);
+// "world"
+
+console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
+// undefined
+
+console.log(
+  Object.getOwnPropertyDescriptor(
+    Object.getPrototypeOf(obj), 'hello'
+  )
+);
+// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.functions.get")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/index.html b/files/zh-cn/web/javascript/reference/functions/index.html new file mode 100644 index 0000000000..9851fa71cb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/index.html @@ -0,0 +1,528 @@ +--- +title: 函数 +slug: Web/JavaScript/Reference/Functions +tags: + - Function + - Functions + - JavaScript +translation_of: Web/JavaScript/Reference/Functions +--- +
{{jsSidebar("Functions")}}
+ +
一般来说,一个函数是可以通过外部代码调用的一个“子程序”(或在递归的情况下由内部函数调用)。像程序本身一样,一个函数由称为函数体的一系列语句组成。值可以传递给一个函数,函数将返回一个值。
+ +
 
+ +
在 JavaScript中,函数是头等(first-class)对象,因为它们可以像任何其他对象一样具有属性和方法。它们与其他对象的区别在于函数可以被调用。简而言之,它们是Function对象。
+ +
 
+ +

有关更多示例和说明,请参阅有关函数的JavaScript指南

+ +

描述

+ +

在JavaScript中,每个函数其实都是一个Function对象。查看{{jsxref("Function")}}页面了解其属性和方法。

+ +

如果一个函数中没有使用return语句,则它默认返回undefined。要想返回一个特定的值,则函数必须使用 return 语句来指定一个要返回的值。(使用new关键字调用一个构造函数除外)。

+ +

调用函数时,传递给函数的值被称为函数的实参(值传递),对应位置的函数参数名叫作形参。如果实参是一个包含原始值(数字,字符串,布尔值)的变量,则就算函数在内部改变了对应形参的值,返回后,该实参变量的值也不会改变。如果实参是一个对象引用,则对应形参会和该实参指向同一个对象。假如函数在内部改变了对应形参的值,返回后,实参指向的对象的值也会改变:

+ +
 /* 定义函数 myFunc */
+ function myFunc(theObject)
+ {
+   //实参 mycar 和形参 theObject 指向同一个对象.
+   theObject.brand = "Toyota";
+ }
+
+ /*
+  * 定义变量 mycar;
+  * 创建并初始化一个对象;
+  * 将对象的引用赋值给变量 mycar
+  */
+ var mycar = {
+   brand: "Honda",
+   model: "Accord",
+   year: 1998
+ };
+
+ /* 弹出 'Honda' */
+ window.alert(mycar.brand);
+
+ /* 将对象引用传给函数 */
+ myFunc(mycar);
+
+ /*
+  * 弹出 'Toyota',对象的属性已被修改.
+  */
+ console.log(mycar.brand);
+
+ +

在函数执行时,this 关键字并不会指向正在运行的函数本身,而是指向调用该函数的对象。所以,如果你想在函数内部获取函数自身的引用,只能使用函数名或者使用arguments.callee属性(严格模式下不可用),如果该函数是一个匿名函数,则你只能使用后者。

+ +

函数定义

+ +

定义函数有多种方法:

+ +

函数声明 (函数语句)

+ +

有一个特殊的语法来声明函数(查看函数语句了解详情):

+ +
function name([param[, param[, ... param]]]) { statements }
+
+ +
+
name
+
函数名.
+
+ +
+
param
+
传递给函数的参数的名称,一个函数最多可以有255个参数。
+
+ +
+
statements
+
组成函数体的声明语句。
+
+ +

函数表达式 (function expression)

+ +

函数表达式和函数声明非常相似,它们甚至有相同的语法(查看函数表达式了解详情)。一个函数表达式可能是一个更大的表达式的一部分。可以定义函数“名字”(例如可以在调用堆栈时使用)或者使用“匿名”函数。函数表达式不会提升,所以不能在定义之前调用。

+ +
var myFunction = function name([param[, param[, ... param]]]) { statements }
+
+ +
+
name
+
函数名,可以省略。当省略函数名的时候,该函数就成为了匿名函数。
+
+ +
+
param
+
传递给函数的参数的名称,一个函数最多可以有255个参数.
+
+ +
+
statements
+
组成函数体的声明语句。
+
+ +

下面是匿名函数的一个例子(函数没有名字):

+ +
var myFunction = function() {
+    // statements
+}
+ +

也可以在定义时为函数命名

+ +
var myFunction = function namedFunction(){
+    // statements
+}
+ +

命名函数表达式的好处是当我们遇到错误时,堆栈跟踪会显示函数名,容易寻找错误。

+ +

可以看到,上面的两个例子都不以function开头。不以function开头的函数语句就是函数表达式定义。

+ +

当函数只使用一次时,通常使用IIFE (Immediately Invokable Function Expressions)。

+ +
(function() {
+    statements
+})();
+ +

IIFE是在函数声明后立即调用的函数表达式。

+ +

函数生成器声明 (function* 语句)

+ +

函数声明有一种特殊的语法 (详情请查阅{{jsxref('Statements/function*', 'function* statement')}} ):

+ +
function* name([param[, param[, ...param]]]) { statements }
+ +
+
name
+
函数名称.
+
param
+
传递给函数的参数的名称,一个函数最多可以有255个参数。
+
statements
+
组成函数体的声明语句。
+
+ +

函数生成器表达式 (function*表达式)

+ +

构造函数表达式和函数声明类似,并且有着相同的语法 (详情请查阅  {{jsxref('Operators/function*', 'function* expression')}} ):

+ +
function* [name]([param] [, param] [..., param]) { statements }
+ +
+
name
+
函数名称。函数名可以被省略,在这种情况下该函数将变成匿名函数。
+
param
+
传递给函数的参数的名称。一个函数可以有多达255个参数
+
statements
+
组成函数体的声明语句。
+
+ +

箭头函数表达式 (=>)

+ +

箭头函数表达式有着更短的语法,并在词汇方面结合这个值  (详情请查阅 arrow functions ):

+ +
([param] [, param]) => { statements } param => expression
+ +
+
param
+
参数名称. 零参数需要用()表示.  只有一个参数时不需要括号. (例如 foo => 1)
+
statements or expression
+
多个声明statements需要用大括号括起来,而单个表达式时则不需要。表达式expression也是该函数的隐式返回值。
+
+ +

 Function构造函数

+ +
+

注意: 不推荐使用 Function 构造函数创建函数,因为它需要的函数体作为字符串可能会阻止一些JS引擎优化,也会引起其他问题。

+
+ +

所有其他对象, {{jsxref("Function")}} 对象可以用new操作符创建:

+ +
new Function (arg1arg2, ... argNfunctionBody)
+ +
+
arg1, arg2, ... argN
+
函数使用零个或多个名称作为正式的参数名称。每一个必须是一个符合有效的JavaScript标识符规则的字符串或用逗号分隔的字符串列表,例如“x”,“theValue”或“a,b”。
+
+ +
+
functionBody
+
一个构成的函数定义的,包含JavaScript声明语句的字符串。
+
+ +

把Function的构造函数当作函数一样调用(不使用new操作符)的效果与作为Function的构造函数调用一样。

+ +

生成器函数的构造函数

+ +
+

注意: GeneratorFunction 不是一个全局对象,但可以从构造函数实例取得。(详情请查阅生成器函数).

+
+ +
+

注意: 不推荐使用构造器函数的构造函数 (GeneratorFunction constructor)创建函数,因为它需要的函数体作为字符串可能会阻止一些JS引擎优化,也会引起其他问题。

+
+ +

所有其他对象, {{jsxref("GeneratorFunction")}} 对象可以用 new 操作符创建:

+ +
new GeneratorFunction (arg1arg2, ... argNfunctionBody)
+ +
+
arg1, arg2, ... argN
+
函数使用零个或多个名称作为正式的参数名称。每一个必须是一个符合有效的JavaScript标识符规则的字符串或用逗号分隔的字符串列表,例如“x”,“theValue”或“a,b”。
+
+ +
+
functionBody
+
一个构成的函数定义的,包含JavaScript声明语句的字符串。
+
+ +

把Function的构造函数当作函数一样调用(不使用new操作符)的效果与作为Function的构造函数调用一样。

+ +

函数参数

+ +

默认参数

+ +

如果没有值或传入了未定义的值,默认函数参数允许形式参数使用默认值初始化。 参见:默认参数

+ +

剩余参数

+ +

剩余参数语法允许将数量不限的参数描述成一个数组。 参见:剩余参数

+ +

arguments对象

+ +

你可以参阅在函数里使用arguments对象的函数参数。参见: arguments

+ + + +

方法函数定义

+ +

Getter 和 setter 函数

+ +

你可以在支持添加新属性的任何标准的内置对象或用户定义的对象内定义getter(访问方法)和setter(设置方法)。使用对象字面量语法定义getters和setters方法。

+ +
+
get
+
+

当查找某个对象属性时,该对象属性将会与被调用函数绑定。

+
+
set
+
当试图设置该属性时,对象属性与被调用函数绑定。
+
+ +

方法定义语法

+ +

从ECMAScript 6开始, 你可以用更短的语法定义自己的方法,类似于getters和setters。详情请查阅 method definitions .

+ +
 var obj = {
+   foo() {},
+   bar() {}
+ };
+
+ +

构造函数 vs 函数声明 vs 函数表达式

+ +

对比下面的例子:

+ +

一个用Function构造函数定义的函数,被赋值给变量multiply:

+ +
var multiply = new Function('x', 'y', 'return x * y');
+ +

一个名为multiply的函数声明:

+ +
function multiply(x, y) {
+   return x * y;
+} // 没有分号
+
+ +

一个匿名函数的函数表达式,被赋值给变量multiply

+ +
 var multiply = function(x, y) {
+   return x * y;
+ };
+
+ +

一个命名为func_named的函数的函数表达式,被赋值给变量multiply

+ +
var multiply = function func_name(x, y) {
+   return x * y;
+};
+ +

差别

+ +

虽然有一些细微的差别,但所起的作用都差不多:

+ +

函数名和函数的变量存在着差别。函数名不能被改变,但函数的变量却能够被再分配。函数名只能在函数体内使用。倘若在函数体外使用函数名将会导致错误(如果函数之前是通过一个var语句声明的则是undefined)。例如:

+ +
var y = function x() {};
+alert(x); // throws an error
+
+ +

当函数是通过 Function's toString method被序列化时,函数名同样也会出现。

+ +

另一方面,被函数赋值的变量仅仅受限于它的作用域,该作用域确保包含着该函数被声明时的作用域。

+ +

正如第四个例子所展示的那样,函数名与被函数赋值的变量是不相同的. 彼此之间没有关系。函数声明同时也创建了一个和函数名相同的变量。因此,与函数表达式定义不同,以函数声明定义的函数能够在它们被定义的作用域内通过函数名而被访问到:

+ +

使用用 'new Function'定义的函数没有函数名。 然而,在 SpiderMonkey JavaScript引擎中,其函数的序列化形式表现的好像它拥有一个名叫"anonymous"的名称一样。比如,使用 alert(new Function()) 输出:

+ +
function anonymous() {
+}
+ +

而实际上其函数并没有名称,anonymous 不是一个可以在函数内被访问到的变量。例如,下面的例子将会导致错误:

+ +
var foo = new Function("alert(anonymous);");
+foo();
+
+ +

和通过函数表达式定义或者通过Function构造函数定义的函数不同,函数声明定义的函数可以在它被声明之前使用。举个例子:

+ +
foo(); // alerts FOO!
+function foo() {
+   alert('FOO!');
+}
+ +

函数表达式定义的函数继承了当前的作用域。换言之,函数构成了闭包。另一方面,Function构造函数定义的函数不继承任何全局作用域以外的作用域(那些所有函数都继承的)。

+ +

通过函数表达式定义的函数和通过函数声明定义的函数只会被解析一次,而Function构造函数定义的函数却不同。也就是说,每次构造函数被调用,传递给Function构造函数的函数体字符串都要被解析一次 。虽然函数表达式每次都创建了一个闭包,但函数体不会被重复解析,因此函数表达式仍然要快于"new Function(...)"。 所以Function构造函数应尽可能地避免使用。

+ +

有一点应该要注意的,在通过解析Function构造函数字符串产生的函数里,内嵌的函数表达式和函数声明不会被重复解析。例如:

+ +
var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
+foo(); // 函数体字符串"function() {\n\talert(bar);\n}"的这一部分不会被重复解析。
+ +

函数声明非常容易(经常是意外地)转换为函数表达式。当它不再是一个函数声明:

+ + + +
var x = 0;               // source element
+if (x === 0) {           // source element
+   x = 10;               // 非source element
+   function boo() {}     // 非 source element
+}
+function foo() {         // source element
+   var y = 20;           // source element
+   function bar() {}     // source element
+   while (y === 10) {    // source element
+      function blah() {} // 非 source element
+      y++;               //非source element
+   }
+}
+
+ +

例子

+ +
// 函数声明
+function foo() {}
+
+// 函数表达式
+(function bar() {})
+
+// 函数表达式
+x = function hello() {}
+
+if (x) {
+   // 函数表达式
+   function world() {}
+}
+
+// 函数声明
+function a() {
+   // 函数声明
+   function b() {}
+   if (0) {
+      //函数表达式
+      function c() {}
+   }
+}
+
+ +

块级函数

+ +

从ECMAScript 6开始,在严格模式下,块里的函数作用域为这个块。ECMAScript 6之前不建议块级函数在严格模式下使用。

+ +
'use strict';
+
+function f() {
+  return 1;
+}
+
+{
+  function f() {
+    return 2;
+  }
+}
+
+f() === 1; // true
+
+// f() === 2 in non-strict mode
+ +

非严格模式下的块级函数

+ +

一句话:不要用。

+ +

在非严格模式下,块中的函数声明表现奇怪。例如:

+ +
if (shouldDefineZero) {
+   function zero() {     // DANGER: 兼容性风险
+      console.log("This is zero.");
+   }
+}
+
+ +

ECMAScript 6中,如果shouldDefineZero是false,则永远不会定义zero,因为这个块从不执行。然而,这是标准的新的一部分。这是历史遗留问题,无论这个块是否执行,一些浏览器会定义zero。

+ +

严格模式下,所有支持ECMAScript 6的浏览器以相同的方式处理:只有在shouldDefineZero为true的情况下定义zero,并且作用域只是这个块内。

+ +

有条件地定义一个函数的一个更安全的方法是把函数表达式赋给一个变量:

+ +
var zero;
+if (0) {
+   zero = function() {
+      console.log("This is zero.");
+   };
+}
+
+ +

示例

+ +

返回格式化数字

+ +

下面的函数返回一个字符串,其中包含了一个格式化的、以一个由0开头并填充的数字。

+ +
// 这个函数返回一个由0开头并填充的字符串
+function padZeros(num, totalLen) {
+   var numStr = num.toString();             // 用字符串返回值进行初始化
+   var numZeros = totalLen - numStr.length; // 计算zeros顺序
+   for (var i = 1; i <= numZeros; i++) {
+      numStr = "0" + numStr;
+   }
+   return numStr;
+}
+ +

下面的语句调用了padZeros函数:

+ +
var result;
+result = padZeros(42,4); // returns "0042"
+result = padZeros(42,2); // returns "42"
+result = padZeros(5,4);  // returns "0005"
+ +

检测函数是否存在

+ +

你可以通过 typeof 操作符检测一个函数是否存在。在下面的例子中,用一个测试来演示检测window对象是否拥有一个noFunc函数的属性。如果存在,那就使用它;否则就采取其它的一些操作。

+ +
if ('function' === typeof window.noFunc) {
+   // use noFunc()
+ } else {
+   // do something else
+ }
+ +

注意在if语句中,使用了noFunc的引用--在函数名的后面没有括号“()”,所以实际函数并没有被调用。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0
{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ES6')}}New: Arrow functions, Generator functions, default parameters, rest parameters.
{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.functions")}}

+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/method_definitions/index.html b/files/zh-cn/web/javascript/reference/functions/method_definitions/index.html new file mode 100644 index 0000000000..a26e15dc20 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/method_definitions/index.html @@ -0,0 +1,220 @@ +--- +title: 方法的定义 +slug: Web/JavaScript/Reference/Functions/Method_definitions +tags: + - ECMAScript 2015 + - Functions + - JavaScript + - Object + - 语法 +translation_of: Web/JavaScript/Reference/Functions/Method_definitions +--- +
{{JsSidebar("Functions")}}
+ +

从ECMAScript 2015开始,在对象初始器中引入了一种更简短定义方法的语法,这是一种把方法名直接赋给函数的简写方式。

+ +
{{EmbedInteractiveExample("pages/js/functions-definitions.html")}}
+ + + +

语法

+ +
var obj = {
+  property( parameters… ) {},
+  *generator( parameters… ) {},
+  async property( parameters… ) {},
+  async* generator( parameters… ) {},
+
+  // with computed keys:
+  [property]( parameters… ) {},
+  *[generator]( parameters… ) {},
+  async [property]( parameters… ) {},
+
+  // compare getter/setter syntax:
+  get property() {},
+  set property(value) {}
+};
+
+ +

描述

+ +

该简写语法与ECMAScript 2015的gettersetter语法类似。

+ +

如下代码:

+ +
var obj = {
+  foo: function() {
+    /* code */
+  },
+  bar: function() {
+    /* code */
+  }
+};
+ +

现可被简写为:

+ +
var obj = {
+  foo() {
+    /* code */
+  },
+  bar() {
+    /* code */
+  }
+};
+ +
+

注意:简写语法使用命名函数而不是匿名函数(如…foo: function() {}…)。命名函数可以从函数体调用(这对匿名函数是不可能的,因为没有标识符可以引用)。详细信息,请参阅{{jsxref("Operators/function","function","#Examples")}}。

+
+ +

生成器方法

+ +

生成器方法也可以用这种简写语法定义。使用它们时,

+ + + +
// 用有属性名的语法定义方法(ES6之前):
+var obj2 = {
+  g: function*() {
+    var index = 0;
+    while(true)
+      yield index++;
+  }
+};
+
+// 同一个方法,简写语法:
+var obj2 = {
+  * g() {
+    var index = 0;
+    while(true)
+      yield index++;
+  }
+};
+
+var it = obj2.g();
+console.log(it.next().value); // 0
+console.log(it.next().value); // 1
+ +

Async 方法

+ +

{{jsxref("Statements/async_function", "Async 方法", "", 1)}}也可以使用简写语法来定义。

+ +
// 用有属性名的语法定义方法(ES6之前):
+var obj3 = {
+  f: async function () {
+    await some_promise;
+  }
+};
+
+// 同一个方法,简写语法:
+var obj3 = {
+  async f() {
+    await some_promise;
+  }
+};
+ +

Async 生成器方法

+ +

生成器方法也能成为 {{jsxref("Statements/async_function", "async", "", 1)}}.

+ +
var obj4 = {
+  f: async function* () {
+    yield 1;
+    yield 2;
+    yield 3;
+  }
+};
+
+// The same object using shorthand syntax
+var obj4 = {
+  async* f() {
+   yield 1;
+   yield 2;
+   yield 3;
+  }
+};
+ +

方法定义不是构造函数

+ +

所有方法定义不是构造函数,如果您尝试实例化它们,将抛出{{jsxref("TypeError")}}。

+ +
var obj = {
+  method() {}
+};
+new obj.method; // TypeError: obj.method is not a constructor
+
+var obj = {
+  * g() {}
+};
+new obj.g; // TypeError: obj.g is not a constructor (changed in ES2016)
+
+ +

示例

+ +

简单示例

+ +
var obj = {
+  a : "foo",
+  b(){ return this.a; }
+};
+console.log(obj.b()); // "foo"
+
+ +

计算的属性名

+ +

该简写语法还支持计算的属性名称作为方法名。

+ +
var bar = {
+  foo0: function() { return 0; },
+  foo1() { return 1; },
+  ['foo' + 2]() { return 2; }
+};
+
+console.log(bar.foo0()); // 0
+console.log(bar.foo1()); // 1
+console.log(bar.foo2()); // 2
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ES2016', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES2016')}}Changed that generator methods should also not have a [[Construct]] trap and will throw when used with new.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.functions.method_definitions")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/rest_parameters/index.html b/files/zh-cn/web/javascript/reference/functions/rest_parameters/index.html new file mode 100644 index 0000000000..04ddd4243d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/rest_parameters/index.html @@ -0,0 +1,168 @@ +--- +title: 剩余参数 +slug: Web/JavaScript/Reference/Functions/Rest_parameters +tags: + - Functions + - JavaScript + - Rest + - Rest parameters +translation_of: Web/JavaScript/Reference/Functions/rest_parameters +--- +
{{jsSidebar("Functions")}}
+ +

剩余参数语法允许我们将一个不定数量的参数表示为一个数组。

+ +
{{EmbedInteractiveExample("pages/js/functions-restparameters.html")}}
+ + + +

语法

+ +
function(a, b, ...theArgs) {
+  // ...
+}
+
+ +

描述

+ +

如果函数的最后一个命名参数以...为前缀,则它将成为一个由剩余参数组成的真数组,其中从0(包括)到theArgs.length(排除)的元素由传递给函数的实际参数提供。

+ +

在上面的例子中,theArgs将收集该函数的第三个参数(因为第一个参数被映射到a,而第二个参数映射到b)和所有后续参数。

+ +

剩余参数和 arguments对象的区别

+ +

剩余参数和 arguments对象之间的区别主要有三个:

+ + + +

从 arguments 到数组

+ +

引入了剩余参数来减少由参数引起的样板代码。

+ +
// Before rest parameters, "arguments" could be converted to a normal array using:
+
+function f(a, b) {
+
+  var normalArray = Array.prototype.slice.call(arguments);
+  // -- or --
+  var normalArray = [].slice.call(arguments);
+  // -- or --
+  var normalArray = Array.from(arguments);
+
+  var first = normalArray.shift(); // OK, gives the first argument
+  var first = arguments.shift(); // ERROR (arguments is not a normal array)
+
+}
+
+// Now we can easily gain access to a normal array using a rest parameter
+
+function f(...args) {
+  var normalArray = args;
+  var first = normalArray.shift(); // OK, gives the first argument
+}
+ +

解构剩余参数

+ +

剩余参数可以被解构,这意味着他们的数据可以被解包到不同的变量中。请参阅解构赋值

+ +
function f(...[a, b, c]) {
+  return a + b + c;
+}
+
+f(1)          // NaN (b and c are undefined)
+f(1, 2, 3)    // 6
+f(1, 2, 3, 4) // 6 (the fourth parameter is not destructured)
+ +

示例

+ +

因为theArgs是个数组,所以你可以使用length属性得到剩余参数的个数:

+ +
function fun1(...theArgs) {
+  alert(theArgs.length);
+}
+
+fun1();  // 弹出 "0", 因为theArgs没有元素
+fun1(5); // 弹出 "1", 因为theArgs只有一个元素
+fun1(5, 6, 7); // 弹出 "3", 因为theArgs有三个元素
+ +

下例中,剩余参数包含了从第二个到最后的所有实参,然后用第一个实参依次乘以它们:

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(function (element) {
+    return multiplier * element;
+  });
+}
+
+var arr = multiply(2, 1, 2, 3);
+console.log(arr);  // [2, 4, 6]
+
+ +

下例演示了你可以在剩余参数上使用任意的数组方法,而arguments对象不可以:

+ +
function sortRestArgs(...theArgs) {
+  var sortedArgs = theArgs.sort();
+  return sortedArgs;
+}
+
+alert(sortRestArgs(5,3,7,1)); // 弹出 1,3,5,7
+
+function sortArguments() {
+  var sortedArgs = arguments.sort();
+  return sortedArgs; // 不会执行到这里
+}
+
+alert(sortArguments(5,3,7,1)); // 抛出TypeError异常:arguments.sort is not a function
+
+ +

为了在arguments对象上使用Array方法,它必须首先被转换为一个真正的数组。

+ +
function sortArguments() {
+  var args = Array.prototype.slice.call(arguments);
+  var sortedArgs = args.sort();
+  return sortedArgs;
+}
+console.log(sortArguments(5, 3, 7, 1)); // shows 1, 3, 5, 7
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ES6')}}Initial definition
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.functions.rest_parameters")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/functions/set/index.html b/files/zh-cn/web/javascript/reference/functions/set/index.html new file mode 100644 index 0000000000..bb49eb1e39 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/functions/set/index.html @@ -0,0 +1,135 @@ +--- +title: setter +slug: Web/JavaScript/Reference/Functions/set +tags: + - ECMAScript 5 + - Functions + - JavaScript +translation_of: Web/JavaScript/Reference/Functions/set +--- +
{{jsSidebar("Functions")}}
+ +

当尝试设置属性时,set语法将对象属性绑定到要调用的函数。

+ +
{{EmbedInteractiveExample("pages/js/functions-setter.html")}}
+ + + +

语法

+ +
{set prop(val) { . . . }}
+{set [expression](val) { . . . }}
+ +

参数

+ +
+
prop
+
要绑定到给定函数的属性名。
+
+ +
+
val
+
用于保存尝试分配给prop的值的变量的一个别名。
+
表达式
+
从 ECMAScript 2015 开始,还可以使用一个计算属性名的表达式绑定到给定的函数。
+
+ +

描述

+ +

在 javascript 中,如果试着改变一个属性的值,那么对应的 setter 将被执行。setter 经常和 getter 连用以创建一个伪属性。不可能在具有真实值的属性上同时拥有一个 setter 器。

+ +

使用 set 语法时请注意:

+ +
+ +
+ +

示例

+ +

在对象初始化时定义 setter

+ +

这将定义一个对象 language 的伪属性current,当current被分配一个值时,将使用该值更新log

+ +
const language = {
+  set current(name) {
+    this.log.push(name);
+  },
+  log: []
+}
+
+language.current = 'EN';
+console.log(language.log); // ['EN']
+
+language.current = 'FA';
+console.log(language.log); // ['EN', 'FA']
+ +

请注意,current属性是未定义的,访问它时将会返回 undefined

+ +

delete 操作符移除一个 setter

+ +

我们可以使用delete操作符移除 setter。

+ +
delete language.current;
+
+ +

使用 defineProperty 为当前对象定义 setter

+ +

我们可以随时使用 {{jsxref("Object.defineProperty()")}} 给一个已经存在的对象添加一个 setter。

+ +
const o = { a:0 };
+
+Object.defineProperty(o, "b", { set: function (x) { this.a = x / 2; } });
+
+o.b = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
+console.log(o.a) // 5
+ +

使用计算属性名

+ +
const expr = "foo";
+
+const obj = {
+  baz: "bar",
+  set [expr](v) { this.baz = v; }
+};
+
+console.log(obj.baz); // "bar"
+obj.foo = "baz";      // run the setter
+console.log(obj.baz); // "baz"
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.functions.set")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/aggregateerror/index.html b/files/zh-cn/web/javascript/reference/global_objects/aggregateerror/index.html new file mode 100644 index 0000000000..ddc0486653 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/aggregateerror/index.html @@ -0,0 +1,106 @@ +--- +title: AggregateError +slug: Web/JavaScript/Reference/Global_Objects/AggregateError +translation_of: Web/JavaScript/Reference/Global_Objects/AggregateError +--- +
+

{{JSRef}}{{Draft}}{{SeeCompatTable}}

+
+ +

AggregateError当多个错误​​需要包装在一个错误中时,对象表示一个错误。

+ +

语法

+ +
new AggregateError(errors[, message])
+ +

参数

+ +
+
errors
+
错误的描述,默认为空。
+
message{{Optional_Inline}}
+
AggregateError错误的提示信息。
+
+ +

描述

+ +

一个AggregateError当需要由操作报告多个错误被抛出,例如通过Promise.any(),在传递给它的所有Promise拒绝。

+ +

属性

+ +
+
AggregateError.prototype
+
AggregateError的原
+
+ +

AggregateError 实例

+ +

实例属性

+ +
+
AggregateError.prototype.constructor
+
指定创建实例原型的函数。
+
{{JSxRef("Error.prototype.message", "AggregateError.prototype.message")}}
+
错误消息,默认为""
+
{{JSxRef("Error.prototype.name", "AggregateError.prototype.name")}}
+
错误名称,默认为"AggregateError"
+
+ +

示例

+ +

捕获一个AggregateError

+ +
Promise.any([
+  Promise.reject(new Error("some error")),
+]).catch(e => {
+  console.log(e instanceof AggregateError); // true
+  console.log(e.message);                   // "All Promises rejected"
+  console.log(e.name);                      // "AggregateError"
+  console.log(e.errors);                    // [ Error: "some error" ]
+});
+
+ +

创建一个AggregateError

+ +
try {
+  throw new AggregateError([
+    new Error("some error"),
+  ], 'Hello');
+} catch (e) {
+  console.log(e instanceof AggregateError); // true
+  console.log(e.message);                   // "Hello"
+  console.log(e.name);                      // "AggregateError"
+  console.log(e.errors);                    // [ Error: "some error" ]
+}
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
ESNext Promise.any ProposalStage 3 DraftInitial definition.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.AggregateError")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/@@iterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/@@iterator/index.html new file mode 100644 index 0000000000..31fe03d8b1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/@@iterator/index.html @@ -0,0 +1,114 @@ +--- +title: 'Array.prototype[@@iterator]()' +slug: Web/JavaScript/Reference/Global_Objects/Array/@@iterator +tags: + - Array + - ECMAScript 2015 + - Iterator + - JavaScript + - Method + - Prototype + - 原型 + - 参考 + - 循环 + - 方法 + - 迭代 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/@@iterator +--- +
{{JSRef}}
+ +

@@iterator 属性和 {{jsxref("Array.prototype.values()", "Array.prototype.values()")}} 属性的初始值是同一个函数对象。

+ +

语法

+ +
arr[Symbol.iterator]()
+ +

返回值

+ +

数组的 iterator 方法,默认情况下,与 {{jsxref("Array.prototype.values()", "values()")}} 返回值相同, arr[Symbol.iterator] 则会返回 {{jsxref("Array.prototype.values()", "values()")}} 函数。

+ +

示例

+ +

使用 for...of 循环进行迭代

+ +
var arr = ['a', 'b', 'c', 'd', 'e'];
+var eArr = arr[Symbol.iterator]();
+// 浏览器必须支持 for...of 循环
+for (let letter of eArr) {
+  console.log(letter);
+}
+
+ +

另一种迭代方式

+ +
var arr = ['a', 'b', 'c', 'd', 'e'];
+var eArr = arr[Symbol.iterator]();
+console.log(eArr.next().value); // a
+console.log(eArr.next().value); // b
+console.log(eArr.next().value); // c
+console.log(eArr.next().value); // d
+console.log(eArr.next().value); // e
+
+ +

Use Case for brace notation

+ +

The use case for this syntax over using the dot notation (Array.prototype.values()) is in a case where you don't know what object is going to be ahead of time. If you have a function that takes an iterator and then iterate over the value, but don't know if that Object is going to have a [Iterable].prototype.values method. This could be a built-in object like String object or a custom object.

+ +
function logIterable(it) {
+  var iterator = it[Symbol.iterator]();
+  // 浏览器必须支持 for...of 循环
+  for (let letter of iterator) {
+      console.log(letter);
+  }
+}
+
+// Array
+logIterable(['a', 'b', 'c']);
+// a
+// b
+// c
+
+// string
+logIterable('abc');
+// a
+// b
+// c
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES6', '#sec-array.prototype-@@iterator', 'Array.prototype[@@iterator]()')}}{{Spec2('ES6')}}首次定义
{{SpecName('ESDraft', '#sec-array.prototype-@@iterator', 'Array.prototype[@@iterator]()')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.@@iterator")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/@@species/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/@@species/index.html new file mode 100644 index 0000000000..cc87927e5e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/@@species/index.html @@ -0,0 +1,78 @@ +--- +title: 'get Array[@@species]' +slug: Web/JavaScript/Reference/Global_Objects/Array/@@species +tags: + - JavaScript + - 原型 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/@@species +--- +
{{JSRef}}
+ +

Array[@@species] 访问器属性返回 Array 的构造函数。

+ +

语法

+ +
Array[Symbol.species]
+
+ +

返回值

+ +

{{jsxref("Array")}} 的构造函数。

+ +

描述

+ +

species 访问器属性返回 Array 对象的默认构造函数。子类的构造函数可能会覆盖并改变构造函数的赋值。

+ +

示例

+ +

species 属性返回默认构造函数, 它用于 Array 对象的构造函数 Array:

+ +
Array[Symbol.species]; // function Array()
+ +

在继承类的对象中(例如你自定义的数组 MyArray),MyArray 的 species 属性返回的是 MyArray 这个构造函数. 然而你可能想要覆盖它,以便在你继承的对象 MyArray 中返回父类的构造函数 Array :

+ +
class MyArray extends Array {
+  // 重写 MyArray 的 species 属性到父类 Array 的构造函数
+  static get [Symbol.species]() { return Array; }
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES6', '#sec-get-array-@@species', 'get Array [ @@species ]')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-get-array-@@species', 'get Array [ @@species ]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.@@species")}}

+
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/@@unscopables/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/@@unscopables/index.html new file mode 100644 index 0000000000..b370dd1281 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/@@unscopables/index.html @@ -0,0 +1,89 @@ +--- +title: 'Array.prototype[@@unscopables]' +slug: Web/JavaScript/Reference/Global_Objects/Array/@@unscopables +tags: + - Array + - ECMAScript 2015 + - JavaScript + - Property + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Array/@@unscopables +--- +
{{JSRef}}
+ +

Symbol 属性 @@unscopable 包含了所有 ES2015 (ES6) 中新定义的、且并未被更早的 ECMAScript 标准收纳的属性名。这些属性被排除在由 with 语句绑定的环境中。

+ +

语法

+ +
arr[Symbol.unscopables]
+ +

描述

+ +

with 绑定中未包含的数组默认属性有:

+ + + + + +

参考 {{jsxref("Symbol.unscopables")}} 以了解如何为自定义的对象设置 unscopables

+ +

{{js_property_attributes(0,0,1)}}

+ +

示例

+ +

以下的代码在 ES5 或更早的版本中能正常工作。然而 ECMAScript 2015 (ES6) 或之后的版本中新添加了 {{jsxref("Array.prototype.keys()")}} 这个方法。这意味着在 with 语句的作用域中,"keys"只能作为方法,而不能作为某个变量。这正是内置的 @@unscopablesArray.prototype[@@unscopables] symbol 属性所要解决的问题:防止某些数组方法被添加到 with 语句的作用域内。

+ +
var keys = [];
+
+with(Array.prototype) {
+  keys.push("something");
+}
+
+Object.keys(Array.prototype[Symbol.unscopables]);
+// ["copyWithin", "entries", "fill", "find", "findIndex",
+//  "includes", "keys", "values"]
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES6', '#sec-array.prototype-@@unscopables', 'Array.prototype[@@unscopables]')}}{{Spec2('ES6')}}首次定义
{{SpecName('ESDraft', '#sec-array.prototype-@@unscopables', 'Array.prototype[@@unscopables]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.@@unscopables")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/concat/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/concat/index.html new file mode 100644 index 0000000000..22911acb9d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/concat/index.html @@ -0,0 +1,158 @@ +--- +title: Array.prototype.concat() +slug: Web/JavaScript/Reference/Global_Objects/Array/concat +tags: + - JavaScript + - 原型 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/concat +--- +
{{JSRef}}
+ +

 concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

+ +

{{EmbedInteractiveExample("pages/js/array-concat.html")}}

+ +

语法

+ +
var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
+ +

参数

+ +
+
valueN{{optional_inline}}
+
数组和/或值,将被合并到一个新的数组中。如果省略了所有 valueN 参数,则 concat 会返回调用此方法的现存数组的一个浅拷贝。详情请参阅下文描述。
+
+ +

返回值

+ +

新的 {{jsxref("Array")}} 实例。

+ +

描述

+ +

concat方法创建一个新的数组,它由被调用的对象中的元素组成,每个参数的顺序依次是该参数的元素(如果参数是数组)或参数本身(如果参数不是数组)。它不会递归到嵌套数组参数中。

+ +

concat方法不会改变this或任何作为参数提供的数组,而是返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。 原始数组的元素将复制到新数组中,如下所示:

+ + + + + +
+

注意:数组/值在连接时保持不变。此外,对于新数组的任何操作(仅当元素不是对象引用时)都不会对原始数组产生影响,反之亦然。

+
+ +

示例

+ +

连接两个数组

+ +

以下代码将两个数组合并为一个新数组:

+ +
var alpha = ['a', 'b', 'c'];
+var numeric = [1, 2, 3];
+
+alpha.concat(numeric);
+// result in ['a', 'b', 'c', 1, 2, 3]
+ +

连接三个数组

+ +

以下代码将三个数组合并为一个新数组:

+ +
var num1 = [1, 2, 3],
+    num2 = [4, 5, 6],
+    num3 = [7, 8, 9];
+
+var nums = num1.concat(num2, num3);
+
+console.log(nums);
+// results in [1, 2, 3, 4, 5, 6, 7, 8, 9]
+ +

将值连接到数组

+ +

以下代码将三个值连接到数组:

+ +
var alpha = ['a', 'b', 'c'];
+
+var alphaNumeric = alpha.concat(1, [2, 3]);
+
+console.log(alphaNumeric);
+// results in ['a', 'b', 'c', 1, 2, 3]
+ +

合并嵌套数组

+ +

以下代码合并数组并保留引用:

+ +
var num1 = [[1]];
+var num2 = [2, [3]];
+var num3=[5,[6]];
+
+var nums = num1.concat(num2);
+
+console.log(nums);
+// results is [[1], 2, [3]]
+
+var nums2=num1.concat(4,num3);
+
+console.log(nums2)
+// results is [[1], 4, 5,[6]]
+
+// modify the first element of num1
+num1[0].push(4);
+
+console.log(nums);
+// results is [[1, 4], 2, [3]]
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.4.4.4', 'Array.prototype.concat')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype.concat', 'Array.prototype.concat')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.concat', 'Array.prototype.concat')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Array.concat")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/copywithin/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/copywithin/index.html new file mode 100644 index 0000000000..b19fa2fc56 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/copywithin/index.html @@ -0,0 +1,190 @@ +--- +title: Array.prototype.copyWithin() +slug: Web/JavaScript/Reference/Global_Objects/Array/copyWithin +tags: + - ECMAScript 2015 + - JavaScript + - polyfill + - 原型 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/copyWithin +--- +
{{JSRef}}
+ +
copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
+ +
{{EmbedInteractiveExample("pages/js/array-copywithin.html")}}
+ + + +

语法

+ +
arr.copyWithin(target[, start[, end]])
+
+ +

参数

+ +
+
target
+
0 为基底的索引,复制序列到该位置。如果是负数,target 将从末尾开始计算。
+
如果 target 大于等于 arr.length,将会不发生拷贝。如果 targetstart 之后,复制的序列将被修改以符合 arr.length
+
start
+
0 为基底的索引,开始复制元素的起始位置。如果是负数,start 将从末尾开始计算。
+
如果 start 被忽略,copyWithin 将会从0开始复制。
+
end
+
0 为基底的索引,开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。如果是负数, end 将从末尾开始计算。
+
如果 end 被忽略,copyWithin 方法将会一直复制至数组结尾(默认为 arr.length)。
+
+ +

返回值

+ +

改变后的数组。

+ +

描述

+ +

参数 target、start 和 end 必须为整数。

+ +

如果 start 为负,则其指定的索引位置等同于 length+start,length 为数组的长度。end 也是如此。

+ +

copyWithin 方法不要求其 this 值必须是一个数组对象;除此之外,copyWithin 是一个可变方法,它可以改变 this 对象本身,并且返回它,而不仅仅是它的拷贝。

+ +

copyWithin 就像 C 和 C++ 的 memcpy 函数一样,且它是用来移动 {{jsxref("Array")}} 或者 {{jsxref("TypedArray")}} 数据的一个高性能的方法。复制以及粘贴序列这两者是为一体的操作;即使复制和粘贴区域重叠,粘贴的序列也会有拷贝来的值。

+ +

copyWithin 函数被设计为通用式的,其不要求其 this 值必须是一个{{jsxref("Array", "数组")}}对象。

+ +

copyWithin 是一个可变方法,它不会改变 this 的长度 length,但是会改变 this 本身的内容,且需要时会创建新的属性。

+ +

例子

+ +
[1, 2, 3, 4, 5].copyWithin(-2)
+// [1, 2, 3, 1, 2]
+
+[1, 2, 3, 4, 5].copyWithin(0, 3)
+// [4, 5, 3, 4, 5]
+
+[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
+// [4, 2, 3, 4, 5]
+
+[1, 2, 3, 4, 5].copyWithin(-2, -3, -1)
+// [1, 2, 3, 3, 4]
+
+[].copyWithin.call({length: 5, 3: 1}, 0, 3);
+// {0: 1, 3: 1, length: 5}
+
+// ES2015 Typed Arrays are subclasses of Array
+var i32a = new Int32Array([1, 2, 3, 4, 5]);
+
+i32a.copyWithin(0, 2);
+// Int32Array [3, 4, 5, 4, 5]
+
+// On platforms that are not yet ES2015 compliant:
+[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
+// Int32Array [4, 2, 3, 4, 5]
+
+ +

Polyfill

+ +
if (!Array.prototype.copyWithin) {
+  Array.prototype.copyWithin = function(target, start/*, end*/) {
+    // Steps 1-2.
+    if (this == null) {
+      throw new TypeError('this is null or not defined');
+    }
+
+    var O = Object(this);
+
+    // Steps 3-5.
+    var len = O.length >>> 0;
+
+    // Steps 6-8.
+    var relativeTarget = target >> 0;
+
+    var to = relativeTarget < 0 ?
+      Math.max(len + relativeTarget, 0) :
+      Math.min(relativeTarget, len);
+
+    // Steps 9-11.
+    var relativeStart = start >> 0;
+
+    var from = relativeStart < 0 ?
+      Math.max(len + relativeStart, 0) :
+      Math.min(relativeStart, len);
+
+    // Steps 12-14.
+    var end = arguments[2];
+    var relativeEnd = end === undefined ? len : end >> 0;
+
+    var final = relativeEnd < 0 ?
+      Math.max(len + relativeEnd, 0) :
+      Math.min(relativeEnd, len);
+
+    // Step 15.
+    var count = Math.min(final - from, len - to);
+
+    // Steps 16-17.
+    var direction = 1;
+
+    if (from < to && to < (from + count)) {
+      direction = -1;
+      from += count - 1;
+      to += count - 1;
+    }
+
+    // Step 18.
+    while (count > 0) {
+      if (from in O) {
+        O[to] = O[from];
+      } else {
+        delete O[to];
+      }
+
+      from += direction;
+      to += direction;
+      count--;
+    }
+
+    // Step 19.
+    return O;
+  };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ES2016', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}}{{Spec2('ES2016')}}
{{SpecName('ESDraft', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.copyWithin")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/entries/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/entries/index.html new file mode 100644 index 0000000000..6d2d0018a8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/entries/index.html @@ -0,0 +1,154 @@ +--- +title: Array.prototype.entries() +slug: Web/JavaScript/Reference/Global_Objects/Array/entries +tags: + - Array.prototype.entries() +translation_of: Web/JavaScript/Reference/Global_Objects/Array/entries +--- +
{{JSRef}}
+ +

entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。

+ +

{{EmbedInteractiveExample("pages/js/array-entries.html")}}

+ +

语法

+ +
arr.entries()
+ +

返回值

+ +

一个新的 {{jsxref("Array")}} 迭代器对象。Array Iterator是对象,它的原型(__proto__:Array Iterator)上有一个next方法,可用用于遍历迭代器取得原数组的[key,value]。

+ +

示例

+ +

1、 Array Iterator

+ +
var arr = ["a", "b", "c"];
+var iterator = arr.entries();
+console.log(iterator);
+
+/*Array Iterator {}
+         __proto__:Array Iterator
+         next:ƒ next()
+         Symbol(Symbol.toStringTag):"Array Iterator"
+         __proto__:Object
+*/
+ +

2、iterator.next()

+ +
var arr = ["a", "b", "c"];
+var iterator = arr.entries();
+console.log(iterator.next());
+
+/*{value: Array(2), done: false}
+          done:false
+          value:(2) [0, "a"]
+           __proto__: Object
+*/
+// iterator.next()返回一个对象,对于有元素的数组,
+// 是next{ value: Array(2), done: false };
+// next.done 用于指示迭代器是否完成:在每次迭代时进行更新而且都是false,
+// 直到迭代器结束done才是true。
+// next.value是一个["key","value"]的数组,是返回的迭代器中的元素值。
+
+ +

3、iterator.next方法运行

+ +
var arr = ["a", "b", "c"];
+var iter = arr.entries();
+var a = [];
+
+// for(var i=0; i< arr.length; i++){   // 实际使用的是这个
+for(var i=0; i< arr.length+1; i++){    // 注意,是length+1,比数组的长度大
+    var tem = iter.next();             // 每次迭代时更新next
+    console.log(tem.done);             // 这里可以看到更新后的done都是false
+    if(tem.done !== true){             // 遍历迭代器结束done才是true
+        console.log(tem.value);
+        a[i]=tem.value;
+    }
+}
+
+console.log(a);                         // 遍历完毕,输出next.value的数组
+ +

4、二维数组按行排序

+ +
function sortArr(arr) {
+    var goNext = true;
+    var entries = arr.entries();
+    while (goNext) {
+        var result = entries.next();
+        if (result.done !== true) {
+            result.value[1].sort((a, b) => a - b);
+            goNext = true;
+        } else {
+            goNext = false;
+        }
+    }
+    return arr;
+}
+
+var arr = [[1,34],[456,2,3,44,234],[4567,1,4,5,6],[34,78,23,1]];
+sortArr(arr);
+
+/*(4) [Array(2), Array(5), Array(5), Array(4)]
+    0:(2) [1, 34]
+    1:(5) [2, 3, 44, 234, 456]
+    2:(5) [1, 4, 5, 6, 4567]
+    3:(4) [1, 23, 34, 78]
+    length:4
+    __proto__:Array(0)
+*/
+
+ +

5、使用for…of 循环

+ +
var arr = ["a", "b", "c"];
+var iterator = arr.entries();
+// undefined
+
+for (let e of iterator) {
+    console.log(e);
+}
+
+// [0, "a"]
+// [1, "b"]
+// [2, "c"]
+
+ +

规范

+ + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES6', '#sec-array.prototype.entries', 'Array.prototype.entries')}}{{Spec2('ES6')}}首次定义
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.entries")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/every/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/every/index.html new file mode 100644 index 0000000000..a64c25b43d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/every/index.html @@ -0,0 +1,194 @@ +--- +title: Array.prototype.every() +slug: Web/JavaScript/Reference/Global_Objects/Array/every +tags: + - ECMAScript 5 + - JavaScript + - polyfill + - 原型 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/every +--- +
{{JSRef}}
+ +

every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。

+ +
+

注意:若收到一个空数组,此方法在一切情况下都会返回 true

+
+ +
{{EmbedInteractiveExample("pages/js/array-every.html")}}
+ + + +

语法

+ +
arr.every(callback(element[, index[, array]])[, thisArg])
+ +

参数

+ +
+
callback
+
用来测试每个元素的函数,它可以接收三个参数: +
+
element
+
用于测试的当前值。
+
index{{Optional_inline}}
+
用于测试的当前值的索引。
+
array{{Optional_inline}}
+
调用 every 的当前数组。
+
+
+
thisArg
+
执行 callback 时使用的 this 值。
+
+ +

返回值

+ +

如果回调函数的每一次返回都为 {{Glossary("truthy")}} 值,返回 true ,否则返回 false

+ +

描述

+ +

every 方法为数组中的每个元素执行一次 callback 函数,直到它找到一个会使 callback 返回 {{Glossary("falsy")}} 的元素。如果发现了一个这样的元素,every 方法将会立即返回 false。否则,callback 为每一个元素返回 trueevery 就会返回 truecallback 只会为那些已经被赋值的索引调用。不会为那些被删除或从未被赋值的索引调用。

+ +

callback 在被调用时可传入三个参数:元素值,元素的索引,原数组。

+ +

如果为 every 提供一个 thisArg 参数,则该参数为调用 callback 时的 this 值。如果省略该参数,则 callback 被调用时的 this 值,在非严格模式下为全局对象,在严格模式下传入 undefined。详见 this 条目。

+ +

every 不会改变原数组。

+ +

every 遍历的元素范围在第一次调用 callback 之前就已确定了。在调用 every 之后添加到数组中的元素不会被 callback 访问到。如果数组中存在的元素被更改,则他们传入 callback 的值是 every 访问到他们那一刻的值。那些被删除的元素或从来未被赋值的元素将不会被访问到。

+ +

every 和数学中的"所有"类似,当所有的元素都符合条件才会返回true。正因如此,若传入一个空数组,无论如何都会返回 true。(这种情况属于无条件正确:正因为一个空集合没有元素,所以它其中的所有元素都符合给定的条件。)

+ +

例子

+ +

检测所有数组元素的大小

+ +

下例检测数组中的所有元素是否都大于 10。

+ +
function isBigEnough(element, index, array) {
+  return element >= 10;
+}
+[12, 5, 8, 130, 44].every(isBigEnough);   // false
+[12, 54, 18, 130, 44].every(isBigEnough); // true
+
+ +

使用箭头函数

+ +

箭头函数为上面的检测过程提供了更简短的语法。

+ +
[12, 5, 8, 130, 44].every(x => x >= 10); // false
+[12, 54, 18, 130, 44].every(x => x >= 10); // true
+ +

兼容旧环境(Polyfill)

+ +

在 ECMA-262 第 5 版时,every 被添加进 ECMA-262 标准;因此,在某些实现环境中,它尚未被支持。你可以把下面的代码放到脚本的开头来解决此问题,该代码允许在那些没有原生支持 every 的实现环境中使用它。该算法是 ECMA-262 第 5 版中指定的算法,它假定 Object 和 TypeError 拥有它们的初始值,且 fun.call 等价于 {{jsxref("Function.prototype.call")}}。

+ +
if (!Array.prototype.every) {
+  Array.prototype.every = function(callbackfn, thisArg) {
+    'use strict';
+    var T, k;
+
+    if (this == null) {
+      throw new TypeError('this is null or not defined');
+    }
+
+    // 1. Let O be the result of calling ToObject passing the this
+    //    value as the argument.
+    var O = Object(this);
+
+    // 2. Let lenValue be the result of calling the Get internal method
+    //    of O with the argument "length".
+    // 3. Let len be ToUint32(lenValue).
+    var len = O.length >>> 0;
+
+    // 4. If IsCallable(callbackfn) is false, throw a TypeError exception.
+    if (typeof callbackfn !== 'function') {
+      throw new TypeError();
+    }
+
+    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+    if (arguments.length > 1) {
+      T = thisArg;
+    }
+
+    // 6. Let k be 0.
+    k = 0;
+
+    // 7. Repeat, while k < len
+    while (k < len) {
+
+      var kValue;
+
+      // a. Let Pk be ToString(k).
+      //   This is implicit for LHS operands of the in operator
+      // b. Let kPresent be the result of calling the HasProperty internal
+      //    method of O with argument Pk.
+      //   This step can be combined with c
+      // c. If kPresent is true, then
+      if (k in O) {
+
+        // i. Let kValue be the result of calling the Get internal method
+        //    of O with argument Pk.
+        kValue = O[k];
+
+        // ii. Let testResult be the result of calling the Call internal method
+        //     of callbackfn with T as the this value and argument list
+        //     containing kValue, k, and O.
+        var testResult = callbackfn.call(T, kValue, k, O);
+
+        // iii. If ToBoolean(testResult) is false, return false.
+        if (!testResult) {
+          return false;
+        }
+      }
+      k++;
+    }
+    return true;
+  };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES5.1', '#sec-15.4.4.16', 'Array.prototype.every')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.6.
{{SpecName('ES6', '#sec-array.prototype.every', 'Array.prototype.every')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.every', 'Array.prototype.every')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.every")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/fill/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/fill/index.html new file mode 100644 index 0000000000..2acc9d6d73 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/fill/index.html @@ -0,0 +1,153 @@ +--- +title: Array.prototype.fill() +slug: Web/JavaScript/Reference/Global_Objects/Array/fill +tags: + - Array + - ECMAScript6 + - JavaScript + - Method + - polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/Array/fill +--- +
{{JSRef}} 
+ +

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

+ +

{{EmbedInteractiveExample("pages/js/array-fill.html")}}

+ +

语法

+ +
arr.fill(value[start[end]])
+ +

参数

+ +
+
value
+
用来填充数组元素的值。
+
start {{optional_inline}}
+
起始索引,默认值为0。
+
end {{optional_inline}}
+
终止索引,默认值为 this.length
+
+ +

返回值

+ +

修改后的数组。

+ +

描述

+ +

fill 方法接受三个参数 value, start 以及 end. startend 参数是可选的, 其默认值分别为 0 和 this 对象的 length 属性值。

+ +

如果 start 是个负数, 则开始索引会被自动计算成为 length+start, 其中 length 是 this 对象的 length 属性值。如果 end 是个负数, 则结束索引会被自动计算成为 length+end

+ +

fill 方法故意被设计成通用方法, 该方法不要求 this 是数组对象。

+ +

fill 方法是个可变方法, 它会改变调用它的 this 对象本身, 然后返回它, 而并不是返回一个副本。

+ +

当一个对象被传递给 fill方法的时候, 填充数组的是这个对象的引用。

+ +

示例

+ +
[1, 2, 3].fill(4);               // [4, 4, 4]
+[1, 2, 3].fill(4, 1);            // [1, 4, 4]
+[1, 2, 3].fill(4, 1, 2);         // [1, 4, 3]
+[1, 2, 3].fill(4, 1, 1);         // [1, 2, 3]
+[1, 2, 3].fill(4, 3, 3);         // [1, 2, 3]
+[1, 2, 3].fill(4, -3, -2);       // [4, 2, 3]
+[1, 2, 3].fill(4, NaN, NaN);     // [1, 2, 3]
+[1, 2, 3].fill(4, 3, 5);         // [1, 2, 3]
+Array(3).fill(4);                // [4, 4, 4]
+[].fill.call({ length: 3 }, 4);  // {0: 4, 1: 4, 2: 4, length: 3}
+
+// Objects by reference.
+var arr = Array(3).fill({}) // [{}, {}, {}];
+// 需要注意如果fill的参数为引用类型,会导致都执行都一个引用类型
+// 如 arr[0] === arr[1] 为true
+arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]
+ +

Polyfill

+ +
if (!Array.prototype.fill) {
+  Object.defineProperty(Array.prototype, 'fill', {
+    value: function(value) {
+
+      // Steps 1-2.
+      if (this == null) {
+        throw new TypeError('this is null or not defined');
+      }
+
+      var O = Object(this);
+
+      // Steps 3-5.
+      var len = O.length >>> 0;
+
+      // Steps 6-7.
+      var start = arguments[1];
+      var relativeStart = start >> 0;
+
+      // Step 8.
+      var k = relativeStart < 0 ?
+        Math.max(len + relativeStart, 0) :
+        Math.min(relativeStart, len);
+
+      // Steps 9-10.
+      var end = arguments[2];
+      var relativeEnd = end === undefined ?
+        len : end >> 0;
+
+      // Step 11.
+      var final = relativeEnd < 0 ?
+        Math.max(len + relativeEnd, 0) :
+        Math.min(relativeEnd, len);
+
+      // Step 12.
+      while (k < final) {
+        O[k] = value;
+        k++;
+      }
+
+      // Step 13.
+      return O;
+    }
+  });
+}
+
+ +

如果你确实需要维护已过时的不支持 Object.defineProperty 的 JavaScript 引擎,那么最好完全不向 Array.prototype 添加方法,因为你不能使它不可枚举。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ES6', '#sec-array.prototype.fill', 'Array.prototype.fill')}}{{Spec2('ES6')}}最初定义。
{{SpecName('ESDraft', '#sec-array.prototype.fill', 'Array.prototype.fill')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{Compat("javascript.builtins.Array.fill")}}
+ +
+ +
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/filter/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/filter/index.html new file mode 100644 index 0000000000..c23bf5cb98 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/filter/index.html @@ -0,0 +1,234 @@ +--- +title: Array.prototype.filter() +slug: Web/JavaScript/Reference/Global_Objects/Array/filter +tags: + - ECMAScript 5 + - JavaScript + - Prototype + - polyfill + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/filter +--- +
{{JSRef}}
+ +

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 

+ +

{{EmbedInteractiveExample("pages/js/array-filter.html")}}

+ + + +

语法

+ +
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
+ +

参数

+ +
+
callback
+
用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。它接受以下三个参数:
+
+
+
element
+
数组中当前正在处理的元素。
+
index{{optional_inline}}
+
正在处理的元素在数组中的索引。
+
array{{optional_inline}}
+
调用了 filter 的数组本身。
+
+
+
thisArg{{optional_inline}}
+
执行 callback 时,用于 this 的值。
+
+ +

返回值

+ +

一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。

+ +

描述

+ +

filter 为数组中的每个元素调用一次 callback 函数,并利用所有使得 callback 返回 true 或等价于 true 的值的元素创建一个新数组。callback 只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。那些没有通过 callback 测试的元素会被跳过,不会被包含在新数组中。

+ +

callback 被调用时传入三个参数:

+ +
    +
  1. 元素的值
  2. +
  3. 元素的索引
  4. +
  5. 被遍历的数组本身
  6. +
+ +

如果为 filter 提供一个 thisArg 参数,则它会被作为 callback 被调用时的 this 值。否则,callbackthis 值在非严格模式下将是全局对象,严格模式下为 undefinedcallback 函数最终观察到的 this 值是根据通常函数所看到的 "this"的规则确定的。

+ +

filter 不会改变原数组,它返回过滤后的新数组。

+ +

filter 遍历的元素范围在第一次调用 callback 之前就已经确定了。在调用 filter 之后被添加到数组中的元素不会被 filter 遍历到。如果已经存在的元素被改变了,则他们传入 callback 的值是 filter 遍历到它们那一刻的值。被删除或从来未被赋值的元素不会被遍历到。

+ +

示例

+ +

筛选排除所有较小的值

+ +

下例使用 filter 创建了一个新数组,该数组的元素由原数组中值大于 10 的元素组成。

+ +
function isBigEnough(element) {
+  return element >= 10;
+}
+var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
+// filtered is [12, 130, 44]
+
+ +

过滤 JSON 中的无效条目

+ +

以下示例使用 filter() 创建具有非零 id 的元素的 json。

+ +
var arr = [
+  { id: 15 },
+  { id: -1 },
+  { id: 0 },
+  { id: 3 },
+  { id: 12.2 },
+  { },
+  { id: null },
+  { id: NaN },
+  { id: 'undefined' }
+];
+
+var invalidEntries = 0;
+
+function isNumber(obj) {
+  return obj !== undefined && typeof(obj) === 'number' && !isNaN(obj);
+}
+
+function filterByID(item) {
+  if (isNumber(item.id) && item.id !== 0) {
+    return true;
+  }
+  invalidEntries++;
+  return false;
+}
+
+var arrByID = arr.filter(filterByID);
+
+console.log('Filtered Array\n', arrByID);
+// Filtered Array
+// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
+
+console.log('Number of Invalid Entries = ', invalidEntries);
+// Number of Invalid Entries = 5
+
+ +

在数组中搜索

+ +

下例使用 filter() 根据搜索条件来过滤数组内容。

+ +
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
+
+/**
+ * Array filters items based on search criteria (query)
+ */
+function filterItems(query) {
+  return fruits.filter(function(el) {
+      return el.toLowerCase().indexOf(query.toLowerCase()) > -1;
+  })
+}
+
+console.log(filterItems('ap')); // ['apple', 'grapes']
+console.log(filterItems('an')); // ['banana', 'mango', 'orange']
+ +

ES2015 实现

+ +
const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
+
+/**
+ * Array filters items based on search criteria (query)
+ */
+const filterItems = (query) => {
+  return fruits.filter((el) =>
+    el.toLowerCase().indexOf(query.toLowerCase()) > -1
+  );
+}
+
+console.log(filterItems('ap')); // ['apple', 'grapes']
+console.log(filterItems('an')); // ['banana', 'mango', 'orange']
+
+
+ +

Polyfill

+ +

filter 被添加到 ECMA-262 标准第 5 版中,因此在某些实现环境中不被支持。可以把下面的代码插入到脚本的开头来解决此问题,该代码允许在那些没有原生支持 filter 的实现环境中使用它。该算法是 ECMA-262 第 5 版中指定的算法,假定 fn.call 等价于 {{jsxref("Function.prototype.call")}} 的初始值,且 {{jsxref("Array.prototype.push")}} 拥有它的初始值。

+ +
if (!Array.prototype.filter){
+  Array.prototype.filter = function(func, thisArg) {
+    'use strict';
+    if ( ! ((typeof func === 'Function' || typeof func === 'function') && this) )
+        throw new TypeError();
+
+    var len = this.length >>> 0,
+        res = new Array(len), // preallocate array
+        t = this, c = 0, i = -1;
+    if (thisArg === undefined){
+      while (++i !== len){
+        // checks to see if the key was set
+        if (i in this){
+          if (func(t[i], i, t)){
+            res[c++] = t[i];
+          }
+        }
+      }
+    }
+    else{
+      while (++i !== len){
+        // checks to see if the key was set
+        if (i in this){
+          if (func.call(thisArg, t[i], i, t)){
+            res[c++] = t[i];
+          }
+        }
+      }
+    }
+
+    res.length = c; // shrink down array to proper size
+    return res;
+  };
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES5.1', '#sec-15.4.4.20', 'Array.prototype.filter')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.6.
{{SpecName('ES2015', '#sec-array.prototype.filter', 'Array.prototype.filter')}}{{Spec2('ES2015')}}
{{SpecName('ESDraft', '#sec-array.prototype.filter', 'Array.prototype.filter')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.filter")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/find/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/find/index.html new file mode 100644 index 0000000000..425901f14d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/find/index.html @@ -0,0 +1,200 @@ +--- +title: Array.prototype.find() +slug: Web/JavaScript/Reference/Global_Objects/Array/find +tags: + - ECMAScript6 + - JavaScript + - polyfill + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/find +--- +
{{JSRef}}
+ +

 find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 {{jsxref("undefined")}}。

+ +

{{EmbedInteractiveExample("pages/js/array-find.html")}}

+ +

另请参见  {{jsxref("Array.findIndex", "findIndex()")}} 方法,它返回数组中找到的元素的索引,而不是其值。

+ +

如果你需要找到一个元素的位置或者一个元素是否存在于数组中,使用{{jsxref("Array.prototype.indexOf()")}} 或 {{jsxref("Array.prototype.includes()")}}。

+ +

语法

+ +
arr.find(callback[, thisArg])
+ +

参数

+ +
+
callback
+
在数组每一项上执行的函数,接收 3 个参数: +
+
element
+
当前遍历到的元素。
+
index{{optional_inline}}
+
当前遍历到的索引。
+
array{{optional_inline}}
+
数组本身。
+
+
+
thisArg{{Optional_inline}}
+
执行回调时用作this 的对象。
+
+ +

返回值

+ +

数组中第一个满足所提供测试函数的元素的值,否则返回 {{jsxref("undefined")}}。

+ +

描述

+ +

find方法对数组中的每一项元素执行一次 callback 函数,直至有一个 callback 返回 true。当找到了这样一个元素后,该方法会立即返回这个元素的值,否则返回 {{jsxref("undefined")}}。注意 callback 函数会为数组中的每个索引调用即从 0 length - 1,而不仅仅是那些被赋值的索引,这意味着对于稀疏数组来说,该方法的效率要低于那些只遍历有值的索引的方法。

+ +

callback函数带有3个参数:当前元素的值、当前元素的索引,以及数组本身。

+ +

如果提供了 thisArg参数,那么它将作为每次 callback函数执行时的this ,如果未提供,则使用 {{jsxref("undefined")}}。

+ +

find方法不会改变数组。

+ +

在第一次调用 callback函数时会确定元素的索引范围,因此在 find方法开始执行之后添加到数组的新元素将不会被 callback函数访问到。如果数组中一个尚未被callback函数访问到的元素的值被callback函数所改变,那么当callback函数访问到它时,它的值是将是根据它在数组中的索引所访问到的当前值。被删除的元素仍旧会被访问到,但是其值已经是undefined了。

+ +

示例

+ +

用对象的属性查找数组里的对象

+ +
var inventory = [
+    {name: 'apples', quantity: 2},
+    {name: 'bananas', quantity: 0},
+    {name: 'cherries', quantity: 5}
+];
+
+function findCherries(fruit) {
+    return fruit.name === 'cherries';
+}
+
+console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }
+ +

寻找数组中的质数

+ +

下面的例子展示了如何从一个数组中寻找质数(如果找不到质数则返回{{jsxref("undefined")}})

+ +
function isPrime(element, index, array) {
+  var start = 2;
+  while (start <= Math.sqrt(element)) {
+    if (element % start++ < 1) {
+      return false;
+    }
+  }
+  return element > 1;
+}
+
+console.log([4, 6, 8, 12].find(isPrime)); // undefined, not found
+console.log([4, 5, 8, 12].find(isPrime)); // 5
+
+
+ +

当在回调中删除数组中的一个值时,当访问到这个位置时,其传入的值是 undefined:

+ +
// Declare array with no element at index 2, 3 and 4
+var a = [0,1,,,,5,6];
+
+// Shows all indexes, not just those that have been assigned values
+a.find(function(value, index) {
+  console.log('Visited index ' + index + ' with value ' + value);
+});
+
+// Shows all indexes, including deleted
+a.find(function(value, index) {
+
+  // Delete element 5 on first iteration
+  if (index == 0) {
+    console.log('Deleting a[5] with value ' + a[5]);
+    delete a[5];  // 注:这里只是将a[5]设置为undefined,可以试试用a.pop()删除最后一项,依然会遍历到被删的那一项
+  }
+  // Element 5 is still visited even though deleted
+  console.log('Visited index ' + index + ' with value ' + value);
+});
+ +

Polyfill

+ +

本方法在ECMAScript 6规范中被加入,可能不存在于某些实现中。你可以通过以下代码来补充 Array.prototype.find()

+ +
// https://tc39.github.io/ecma262/#sec-array.prototype.find
+if (!Array.prototype.find) {
+  Object.defineProperty(Array.prototype, 'find', {
+    value: function(predicate) {
+     // 1. Let O be ? ToObject(this value).
+      if (this == null) {
+        throw new TypeError('"this" is null or not defined');
+      }
+
+      var o = Object(this);
+
+      // 2. Let len be ? ToLength(? Get(O, "length")).
+      var len = o.length >>> 0;
+
+      // 3. If IsCallable(predicate) is false, throw a TypeError exception.
+      if (typeof predicate !== 'function') {
+        throw new TypeError('predicate must be a function');
+      }
+
+      // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
+      var thisArg = arguments[1];
+
+      // 5. Let k be 0.
+      var k = 0;
+
+      // 6. Repeat, while k < len
+      while (k < len) {
+        // a. Let Pk be ! ToString(k).
+        // b. Let kValue be ? Get(O, Pk).
+        // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
+        // d. If testResult is true, return kValue.
+        var kValue = o[k];
+        if (predicate.call(thisArg, kValue, k, o)) {
+          return kValue;
+        }
+        // e. Increase k by 1.
+        k++;
+      }
+
+      // 7. Return undefined.
+      return undefined;
+    }
+  });
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-array.prototype.find', 'Array.prototype.find')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-array.prototype.find', 'Array.prototype.find')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Array.find")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/findindex/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/findindex/index.html new file mode 100644 index 0000000000..bd7e039dd0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/findindex/index.html @@ -0,0 +1,165 @@ +--- +title: Array.prototype.findIndex() +slug: Web/JavaScript/Reference/Global_Objects/Array/findIndex +tags: + - Array + - JavaScript + - Method + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Array/findIndex +--- +
{{JSRef}}
+ +

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

+ +
{{EmbedInteractiveExample("pages/js/array-findindex.html")}}
+ + + +

另请参见  {{jsxref("Array.find", "find()")}} 方法,它返回数组中找到的元素的,而不是其索引。

+ +

语法

+ +
arr.findIndex(callback[, thisArg])
+ +

参数

+ +
+
callback
+
针对数组中的每个元素, 都会执行该回调函数, 执行时会自动传入下面三个参数: +
+
element
+
当前元素。
+
index
+
当前元素的索引。
+
array
+
调用findIndex的数组。
+
+
+
thisArg
+
可选。执行callback时作为this对象的值.
+
+ +

返回值

+ +

    数组中通过提供测试函数的第一个元素的索引。否则,返回-1

+ +

描述

+ +

findIndex方法对数组中的每个数组索引0..length-1(包括)执行一次callback函数,直到找到一个callback函数返回真实值(强制为true)的值。如果找到这样的元素,findIndex会立即返回该元素的索引。如果回调从不返回真值,或者数组的length为0,则findIndex返回-1。 与某些其他数组方法(如Array#some)不同,在稀疏数组中,即使对于数组中不存在的条目的索引也会调用回调函数。

+ +

回调函数调用时有三个参数:元素的值,元素的索引,以及被遍历的数组。

+ +

如果一个 thisArg 参数被提供给 findIndex, 它将会被当作this使用在每次回调函数被调用的时候。如果没有被提供,将会使用{{jsxref("undefined")}}。

+ +

findIndex不会修改所调用的数组。

+ +

在第一次调用callback函数时会确定元素的索引范围,因此在findIndex方法开始执行之后添加到数组的新元素将不会被callback函数访问到。如果数组中一个尚未被callback函数访问到的元素的值被callback函数所改变,那么当callback函数访问到它时,它的值是将是根据它在数组中的索引所访问到的当前值。被删除的元素仍然会被访问到。

+ +

示例

+ +

查找数组中首个质数元素的索引

+ +

以下示例查找数组中素数的元素的索引(如果不存在素数,则返回-1)。

+ +
function isPrime(element, index, array) {
+  var start = 2;
+  while (start <= Math.sqrt(element)) {
+    if (element % start++ < 1) {
+      return false;
+    }
+  }
+  return element > 1;
+}
+
+console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
+console.log([4, 6, 7, 12].findIndex(isPrime)); // 2
+ +

Polyfill

+ +
// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
+if (!Array.prototype.findIndex) {
+  Object.defineProperty(Array.prototype, 'findIndex', {
+    value: function(predicate) {
+     // 1. Let O be ? ToObject(this value).
+      if (this == null) {
+        throw new TypeError('"this" is null or not defined');
+      }
+
+      var o = Object(this);
+
+      // 2. Let len be ? ToLength(? Get(O, "length")).
+      var len = o.length >>> 0;
+
+      // 3. If IsCallable(predicate) is false, throw a TypeError exception.
+      if (typeof predicate !== 'function') {
+        throw new TypeError('predicate must be a function');
+      }
+
+      // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
+      var thisArg = arguments[1];
+
+      // 5. Let k be 0.
+      var k = 0;
+
+      // 6. Repeat, while k < len
+      while (k < len) {
+        // a. Let Pk be ! ToString(k).
+        // b. Let kValue be ? Get(O, Pk).
+        // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
+        // d. If testResult is true, return k.
+        var kValue = o[k];
+        if (predicate.call(thisArg, kValue, k, o)) {
+          return k;
+        }
+        // e. Increase k by 1.
+        k++;
+      }
+
+      // 7. Return -1.
+      return -1;
+    }
+  });
+}
+
+ +

如果您需要兼容不支持Object.defineProperty的JavaScript引擎,那么最好不要对Array.prototype方法进行 polyfill ,因为您无法使其成为不可枚举的。

+ +

使用此方法需要注意你是否在uc浏览器环境,如果你的页面在支付宝上使用尤其注意,因为支付宝使用的就是uc浏览器环境.

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-array.prototype.findindex', 'Array.prototype.findIndex')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-array.prototype.findIndex', 'Array.prototype.findIndex')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Array.findIndex")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/flat/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/flat/index.html new file mode 100644 index 0000000000..5346c65b82 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/flat/index.html @@ -0,0 +1,218 @@ +--- +title: Array.prototype.flat() +slug: Web/JavaScript/Reference/Global_Objects/Array/flat +tags: + - JavaScript + - 原型 + - 参考 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/flat +--- +
{{JSRef}}
+ +

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

+ +
{{EmbedInteractiveExample("pages/js/array-flat.html")}}
+ + + +

语法

+ +
var newArray = arr.flat([depth])
+ +

参数

+ +
+
depth {{optional_inline}}
+
指定要提取嵌套数组的结构深度,默认值为 1。
+
+ +

返回值

+ +

一个包含将数组与子数组中所有元素的新数组。

+ +

示例

+ +

扁平化嵌套数组

+ +
var arr1 = [1, 2, [3, 4]];
+arr1.flat();
+// [1, 2, 3, 4]
+
+var arr2 = [1, 2, [3, 4, [5, 6]]];
+arr2.flat();
+// [1, 2, 3, 4, [5, 6]]
+
+var arr3 = [1, 2, [3, 4, [5, 6]]];
+arr3.flat(2);
+// [1, 2, 3, 4, 5, 6]
+
+//使用 Infinity,可展开任意深度的嵌套数组
+var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
+arr4.flat(Infinity);
+// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ +

扁平化与数组空项

+ +

flat() 方法会移除数组中的空项:

+ +
var arr4 = [1, 2, , 4, 5];
+arr4.flat();
+// [1, 2, 4, 5]
+ +

替代方案

+ +

使用 reduceconcat

+ +
var arr = [1, 2, [3, 4]];
+
+// 展开一层数组
+arr.flat();
+// 等效于
+arr.reduce((acc, val) => acc.concat(val), []);
+// [1, 2, 3, 4]
+
+// 使用扩展运算符 ...
+const flattened = arr => [].concat(...arr);
+ +

reduce + concat + isArray + recursivity

+ +
// 使用 reduce、concat 和递归展开无限多层嵌套的数组
+var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
+
+function flatDeep(arr, d = 1) {
+   return d > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val), [])
+                : arr.slice();
+};
+
+flatDeep(arr1, Infinity);
+// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
+ +

forEach+isArray+push+recursivity

+ +
// forEach 遍历数组会自动跳过空元素
+const eachFlat = (arr = [], depth = 1) => {
+  const result = []; // 缓存递归结果
+  // 开始递归
+  (function flat(arr, depth) {
+    // forEach 会自动去除数组空位
+    arr.forEach((item) => {
+      // 控制递归深度
+      if (Array.isArray(item) && depth > 0) {
+        // 递归数组
+        flat(item, depth - 1)
+      } else {
+        // 缓存元素
+        result.push(item)
+      }
+    })
+  })(arr, depth)
+  // 返回递归结果
+  return result;
+}
+
+// for of 循环不能去除数组空位,需要手动去除
+const forFlat = (arr = [], depth = 1) => {
+  const result = [];
+  (function flat(arr, depth) {
+    for (let item of arr) {
+      if (Array.isArray(item) && depth > 0) {
+        flat(item, depth - 1)
+      } else {
+        // 去除空元素,添加非undefined元素
+        item !== void 0 && result.push(item);
+      }
+    }
+  })(arr, depth)
+  return result;
+}
+
+ +

使用堆栈stack

+ +
// 无递归数组扁平化,使用堆栈
+// 注意:深度的控制比较低效,因为需要检查每一个值的深度
+// 也可能在 shift / unshift 上进行 w/o 反转,但是末端的数组 OPs 更快
+var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
+function flatten(input) {
+  const stack = [...input];
+  const res = [];
+  while (stack.length) {
+    // 使用 pop 从 stack 中取出并移除值
+    const next = stack.pop();
+    if (Array.isArray(next)) {
+      // 使用 push 送回内层数组中的元素,不会改动原始输入
+      stack.push(...next);
+    } else {
+      res.push(next);
+    }
+  }
+  // 反转恢复原数组的顺序
+  return res.reverse();
+}
+flatten(arr1);// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
+ +
// 递归版本的反嵌套
+function flatten(array) {
+  var flattend = [];
+  (function flat(array) {
+    array.forEach(function(el) {
+      if (Array.isArray(el)) flat(el);
+      else flattend.push(el);
+    });
+  })(array);
+  return flattend;
+}
+ +

Use Generator function

+ +
function* flatten(array) {
+    for (const item of array) {
+        if (Array.isArray(item)) {
+            yield* flatten(item);
+        } else {
+            yield item;
+        }
+    }
+}
+
+var arr = [1, 2, [3, 4, [5, 6]]];
+const flattened = [...flatten(arr)];
+// [1, 2, 3, 4, 5, 6]
+ +

Please do not add polyfills on this article. For reference, please check: https://discourse.mozilla.org/t/mdn-rfc-001-mdn-wiki-pages-shouldnt-be-a-distributor-of-polyfills/24500

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 2019FinishedInitial definition
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.flat")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/flatmap/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/flatmap/index.html new file mode 100644 index 0000000000..9099d44001 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/flatmap/index.html @@ -0,0 +1,149 @@ +--- +title: Array.prototype.flatMap() +slug: Web/JavaScript/Reference/Global_Objects/Array/flatMap +tags: + - Array + - JavaScript + - Method + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Array/flatMap +--- +
{{JSRef}}
+ +

flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为1的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。

+ + + + + +

语法

+ +
var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
+    // return element for new_array
+}[, thisArg])
+ +

参数

+ +
+
callback
+
可以生成一个新数组中的元素的函数,可以传入三个参数: +
+
+
currentValue
+
当前正在数组中处理的元素
+
index{{optional_inline}}
+
可选的。数组中正在处理的当前元素的索引。
+
array{{optional_inline}}
+
可选的。被调用的 map 数组
+
+
+
thisArg{{optional_inline}}
+
可选的。执行 callback 函数时 使用的this 值。
+
+ +

返回值

+ +

 一个新的数组,其中每个元素都是回调函数的结果,并且结构深度 depth 值为1。

+ +

描述

+ +

有关回调函数的详细描述,请参见 {{jsxref("Array.prototype.map()")}} 。 flatMap 方法与 map 方法和深度depth为1的 flat 几乎相同.

+ +

示例

+ +

map() 与 flatMap()

+ +
var arr1 = [1, 2, 3, 4];
+
+arr1.map(x => [x * 2]);
+// [[2], [4], [6], [8]]
+
+arr1.flatMap(x => [x * 2]);
+// [2, 4, 6, 8]
+
+// only one level is flattened
+arr1.flatMap(x => [[x * 2]]);
+// [[2], [4], [6], [8]]
+ +

虽然上面的代码使用 map 和 flatMap 好像都可以,但这只能展示如何使用 flatMap。

+ +

所以,为了更好的展示 flatMap 的作用,下面我们将包含几句话的数组拆分成单个词组成的新数组。

+ +
let arr1 = ["it's Sunny in", "", "California"];
+
+arr1.map(x => x.split(" "));
+// [["it's","Sunny","in"],[""],["California"]]
+
+arr1.flatMap(x => x.split(" "));
+// ["it's","Sunny","in", "", "California"]
+ +

注意,输出列表长度可以不同于输入列表长度。

+ +

在一个 map() 期间增加或去除一些项

+ +

flatMap 能用于在map期间增删项目(也就是修改items的数量)。换句话说,它允许你遍历很多项使之成为另一些项(靠分别把它们放进去来处理),而不是总是一对一。 从这个意义上讲,它的作用类似于 filter的对立面。只需返回一个1项元素数组以保留该项,返回一个多元素数组以添加项,或返回一个0项元素数组以删除该项。

+ +
// Let's say we want to remove all the negative numbers and split the odd numbers into an even number and a 1
+let a = [5, 4, -3, 20, 17, -33, -4, 18]
+//       |\  \  x   |  | \   x   x   |
+//      [4,1, 4,   20, 16, 1,       18]
+
+a.flatMap( (n) =>
+  (n < 0) ?      [] :
+  (n % 2 == 0) ? [n] :
+                 [n-1, 1]
+)
+
+// expected output: [4, 1, 4, 20, 16, 1, 18]
+ +

替代方案

+ +

reduce() 与 concat()

+ +
var arr = [1, 2, 3, 4];
+
+arr.flatMap(x => [x, x * 2]);
+// is equivalent to
+arr.reduce((acc, x) => acc.concat([x, x * 2]), []);
+// [1, 2, 2, 4, 3, 6, 4, 8]
+ +

请注意,这是低效的,并且应该避免大型阵列:在每次迭代中,它创建一个必须被垃圾收集的新临时数组,并且它将元素从当前的累加器数组复制到一个新的数组中,而不是将新的元素添加到现有的数组中。

+ + + +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-array.prototype.flatmap', 'Array.prototype.flatMap')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.flatMap")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/foreach/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/foreach/index.html new file mode 100644 index 0000000000..020a7dc3cd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/foreach/index.html @@ -0,0 +1,384 @@ +--- +title: Array.prototype.forEach() +slug: Web/JavaScript/Reference/Global_Objects/Array/forEach +tags: + - Array + - ECMAScript5 + - JavaScript + - 参考 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/forEach +--- +
{{JSRef}}
+ +

forEach() 方法对数组的每个元素执行一次给定的函数。

+ + + +

{{EmbedInteractiveExample("pages/js/array-foreach.html")}}

+ +

语法

+ +
arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
+ +

参数

+ +
+
callback
+
为数组中每个元素执行的函数,该函数接收一至三个参数:
+
+
+
currentValue
+
数组中正在处理的当前元素。
+
index {{optional_inline}}
+
数组中正在处理的当前元素的索引。
+
array {{optional_inline}}
+
forEach() 方法正在操作的数组。
+
+
+
thisArg {{optional_inline}}
+
可选参数。当执行回调函数 callback 时,用作 this 的值。
+
+ +

返回值

+ +

{{jsxref("undefined")}}。

+ +

描述

+ +

forEach() 方法按升序为数组中含有效值的每一项执行一次 callback 函数,那些已删除或者未初始化的项将被跳过(例如在稀疏数组上)。

+ +

可依次向 callback 函数传入三个参数:

+ +
    +
  1. 数组当前项的值
  2. +
  3. 数组当前项的索引
  4. +
  5. 数组对象本身
  6. +
+ +

如果 thisArg 参数有值,则每次 callback 函数被调用时,this 都会指向 thisArg 参数。如果省略了 thisArg 参数,或者其值为 nullundefinedthis 则指向全局对象。按照函数观察到 this 的常用规则callback 函数最终可观察到 this 值。

+ +

forEach() 遍历的范围在第一次调用 callback 前就会确定。调用 forEach 后添加到数组中的项不会被 callback 访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach() 遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 {{jsxref("Array.prototype.shift()", "shift()")}}),之后的元素将被跳过——参见下面的示例

+ +

forEach() 为每个数组元素执行一次 callback 函数;与 {{jsxref("Array.prototype.map()", "map()")}} 或者 {{jsxref("Array.prototype.reduce()", "reduce()")}} 不同的是,它总是返回 {{jsxref("undefined")}} 值,并且不可链式调用。其典型用例是在一个调用链的最后执行副作用(side effects,函数式编程上,指函数进行 返回结果值 以外的操作)。

+ +

forEach() 被调用时,不会改变原数组,也就是调用它的数组(尽管 callback 函数在被调用时可能会改变原数组)。(译注:此处说法可能不够明确,具体可参考EMCA语言规范:'forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.',即 forEach 不会直接改变调用它的对象,但是那个对象可能会被 callback 函数改变。)

+ +
+

注意: 除了抛出异常以外,没有办法中止或跳出 forEach() 循环。如果你需要中止或跳出循环,forEach() 方法不是应当使用的工具。

+ +

若你需要提前终止循环,你可以使用:

+ + + +

这些数组方法则可以对数组元素判断,以便确定是否需要继续遍历:

+ + + +

译者注:只要条件允许,也可以使用 {{jsxref("Array.prototype.filter()", "filter()")}} 提前过滤出需要遍历的部分,再用 forEach() 处理。

+
+ +

示例

+ +

不对未初始化的值进行任何操作(稀疏数组)

+ +

如你所见,37 之间空缺的数组单元未被 forEach() 调用 callback 函数,或进行任何其他操作。

+ +
const arraySparse = [1,3,,7];
+let numCallbackRuns = 0;
+
+arraySparse.forEach(function(element){
+  console.log(element);
+  numCallbackRuns++;
+});
+
+console.log("numCallbackRuns: ", numCallbackRuns);
+
+// 1
+// 3
+// 7
+// numCallbackRuns: 3
+ +

将 for 循环转换为 forEach

+ +
const items = ['item1', 'item2', 'item3'];
+const copy = [];
+
+// before
+for (let i=0; i<items.length; i++) {
+  copy.push(items[i]);
+}
+
+// after
+items.forEach(function(item){
+  copy.push(item);
+});
+
+ +

打印出数组的内容

+ +
+

注意:为了在控制台中显示数组的内容,你可以使用 console.table() 来展示经过格式化的数组。下面的例子则是另一种使用 forEach() 的格式化的方法。

+
+ +

下面的代码会为每一个数组元素输出一行记录:

+ +
function logArrayElements(element, index, array) {
+  console.log('a[' + index + '] = ' + element);
+}
+
+// 注意索引 2 被跳过了,因为在数组的这个位置没有项
+[2, 5, , 9].forEach(logArrayElements);
+// logs:
+// a[0] = 2
+// a[1] = 5
+// a[3] = 9
+
+ +

使用 thisArg

+ +

举个勉强的例子,按照每个数组中的元素值,更新一个对象的属性:

+ +
function Counter() {
+  this.sum = 0;
+  this.count = 0;
+}
+Counter.prototype.add = function(array) {
+  array.forEach(function(entry) {
+    this.sum += entry;
+    ++this.count;
+  }, this);
+  // ^---- Note
+};
+
+const obj = new Counter();
+obj.add([2, 5, 9]);
+obj.count;
+// 3 === (1 + 1 + 1)
+obj.sum;
+// 16 === (2 + 5 + 9)
+
+ +

因为 thisArg 参数(this)传给了 forEach(),每次调用时,它都被传给 callback 函数,作为它的 this 值。

+ +
+
注意:如果使用箭头函数表达式来传入函数参数, thisArg 参数会被忽略,因为箭头函数在词法上绑定了 {{jsxref("Operators/this", "this")}} 值。
+
+ +

对象复制器函数

+ +

下面的代码会创建一个给定对象的副本。 创建对象的副本有不同的方法,以下是只是一种方法,并解释了 Array.prototype.forEach() 是如何使用 ECMAScript 5 Object.* 元属性(meta property)函数工作的。

+ +
function copy(obj) {
+  const copy = Object.create(Object.getPrototypeOf(obj));
+  const propNames = Object.getOwnPropertyNames(obj);
+
+  propNames.forEach(function(name) {
+    const desc = Object.getOwnPropertyDescriptor(obj, name);
+    Object.defineProperty(copy, name, desc);
+  });
+
+  return copy;
+}
+
+const obj1 = { a: 1, b: 2 };
+const obj2 = copy(obj1); // 现在 obj2 看起来和 obj1 一模一样了
+
+ +

如果数组在迭代时被修改了,则其他元素会被跳过。

+ +

下面的例子会输出 "one", "two", "four"。当到达包含值 "two" 的项时,整个数组的第一个项被移除了,这导致所有剩下的项上移一个位置。因为元素 "four" 正位于在数组更前的位置,所以 "three" 会被跳过。 forEach() 不会在迭代之前创建数组的副本。

+ +
var words = ['one', 'two', 'three', 'four'];
+words.forEach(function(word) {
+  console.log(word);
+  if (word === 'two') {
+    words.shift();
+  }
+});
+// one
+// two
+// four
+
+ +

扁平化数组

+ +

下面的示例仅用于学习目的。如果你想使用内置方法来扁平化数组,你可以考虑使用 {{jsxref("Array.prototype.flat()")}}(预计将成为 ES2019 的一部分,并且已在主要浏览器中实现)或参考其 polyfill。

+ +
/**
+ * Flattens passed array in one dimensional array
+ *
+ * @params {array} arr
+ * @returns {array}
+ */
+function flatten(arr) {
+  const result = [];
+
+  arr.forEach((i) => {
+    if (Array.isArray(i))
+      result.push(...flatten(i));
+    else
+      result.push(i);
+  })
+
+  return result;
+}
+
+// Usage
+const problem = [1, 2, 3, [4, 5, [6, 7], 8, 9]];
+
+flatten(problem); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+ +

针对 promise 或 async 函数的使用备注

+ +

如果使用 promise 或 async 函数作为 forEach() 等类似方法的 callback 参数,最好对造成的执行顺序影响多加考虑,否则容易出现错误。

+ +
let ratings = [5, 4, 5];
+
+let sum = 0;
+
+let sumFunction = async function (a, b) {
+    return a + b;
+}
+
+ratings.forEach(async function(rating) {
+    sum = await sumFunction(sum, rating);
+})
+
+console.log(sum);
+// Expected output: 14
+// Actual output: 0
+
+ +

Polyfill

+ +

forEach() 是在第五版本里被添加到 ECMA-262 标准的;这样它可能在标准的其他实现中不存在,你可以在你调用 forEach() 之前插入下面的代码,在本地不支持的情况下使用 forEach()。该算法是 ECMA-262 第5版中指定的算法。它假定 {{jsxref("Object")}} 和 {{jsxref("TypeError")}} 拥有它们的初始值,且 callback.call 等价于 {{jsxref("Function.prototype.call()")}}。

+ +
// Production steps of ECMA-262, Edition 5, 15.4.4.18
+// Reference: http://es5.github.io/#x15.4.4.18
+if (!Array.prototype.forEach) {
+
+  Array.prototype.forEach = function(callback, thisArg) {
+
+    var T, k;
+
+    if (this == null) {
+      throw new TypeError(' this is null or not defined');
+    }
+
+    // 1. Let O be the result of calling toObject() passing the
+    // |this| value as the argument.
+    var O = Object(this);
+
+    // 2. Let lenValue be the result of calling the Get() internal
+    // method of O with the argument "length".
+    // 3. Let len be toUint32(lenValue).
+    var len = O.length >>> 0;
+
+    // 4. If isCallable(callback) is false, throw a TypeError exception.
+    // See: http://es5.github.com/#x9.11
+    if (typeof callback !== "function") {
+      throw new TypeError(callback + ' is not a function');
+    }
+
+    // 5. If thisArg was supplied, let T be thisArg; else let
+    // T be undefined.
+    if (arguments.length > 1) {
+      T = thisArg;
+    }
+
+    // 6. Let k be 0
+    k = 0;
+
+    // 7. Repeat, while k < len
+    while (k < len) {
+
+      var kValue;
+
+      // a. Let Pk be ToString(k).
+      //    This is implicit for LHS operands of the in operator
+      // b. Let kPresent be the result of calling the HasProperty
+      //    internal method of O with argument Pk.
+      //    This step can be combined with c
+      // c. If kPresent is true, then
+      if (k in O) {
+
+        // i. Let kValue be the result of calling the Get internal
+        // method of O with argument Pk.
+        kValue = O[k];
+
+        // ii. Call the Call internal method of callback with T as
+        // the this value and argument list containing kValue, k, and O.
+        callback.call(T, kValue, k, O);
+      }
+      // d. Increase k by 1.
+      k++;
+    }
+    // 8. return undefined
+  };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-array.prototype.foreach', 'Array.prototype.forEach')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-array.prototype.foreach', 'Array.prototype.forEach')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-15.4.4.18', 'Array.prototype.forEach')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.6.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.forEach")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/from/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/from/index.html new file mode 100644 index 0000000000..98a16c1700 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/from/index.html @@ -0,0 +1,258 @@ +--- +title: Array.from() +slug: Web/JavaScript/Reference/Global_Objects/Array/from +tags: + - Array + - ECMAScript 2015 + - JavaScript + - Reference + - arguments + - polyfill + - 参考 + - 数组 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/from +--- +
{{JSRef}}
+ +

Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

+ +
{{EmbedInteractiveExample("pages/js/array-from.html")}}
+ + + +

语法

+ +
Array.from(arrayLike[, mapFn[, thisArg]])
+
+ +

参数

+ +
+
arrayLike
+
想要转换成数组的伪数组对象或可迭代对象。
+
mapFn {{Optional_inline}}
+
如果指定了该参数,新数组中的每个元素会执行该回调函数。
+
thisArg {{Optional_inline}}
+
可选参数,执行回调函数 mapFnthis 对象。
+
+ +

返回值

+ +

一个新的{{jsxref("Array","数组")}}实例。

+ +

描述

+ +

Array.from() 可以通过以下方式来创建数组对象:

+ + + +

Array.from() 方法有一个可选参数 mapFn,让你可以在最后生成的数组上再执行一次 {{jsxref("Array.prototype.map", "map")}} 方法后再返回。也就是说 Array.from(obj, mapFn, thisArg) 就相当于 Array.from(obj).map(mapFn, thisArg), 除非创建的不是可用的中间数组。 这对一些数组的子类,typed arrays 来说很重要, 因为中间数组的值在调用 map() 时需要是适当的类型。

+ +

from()length 属性为 1 ,即 Array.from.length === 1

+ +

在 ES2015 中, Class 语法允许我们为内置类型(比如 Array)和自定义类新建子类(比如叫 SubArray)。这些子类也会继承父类的静态方法,比如 SubArray.from(),调用该方法后会返回子类 SubArray 的一个实例,而不是 Array 的实例。

+ +

示例

+ +

String 生成数组

+ +
Array.from('foo');
+// [ "f", "o", "o" ]
+ +

Set 生成数组

+ +
const set = new Set(['foo', 'bar', 'baz', 'foo']);
+Array.from(set);
+// [ "foo", "bar", "baz" ]
+ +

Map 生成数组

+ +
const map = new Map([[1, 2], [2, 4], [4, 8]]);
+Array.from(map);
+// [[1, 2], [2, 4], [4, 8]]
+
+const mapper = new Map([['1', 'a'], ['2', 'b']]);
+Array.from(mapper.values());
+// ['a', 'b'];
+
+Array.from(mapper.keys());
+// ['1', '2'];
+
+ +

从类数组对象(arguments)生成数组

+ +
function f() {
+  return Array.from(arguments);
+}
+
+f(1, 2, 3);
+
+// [ 1, 2, 3 ]
+ +

Array.from 中使用箭头函数

+ +
// Using an arrow function as the map function to
+// manipulate the elements
+Array.from([1, 2, 3], x => x + x);
+// [2, 4, 6]
+
+
+// Generate a sequence of numbers
+// Since the array is initialized with `undefined` on each position,
+// the value of `v` below will be `undefined`
+Array.from({length: 5}, (v, i) => i);
+// [0, 1, 2, 3, 4]
+
+ +

序列生成器(指定范围)

+ +
// Sequence generator function (commonly referred to as "range", e.g. Clojure, PHP etc)
+const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
+
+// Generate numbers range 0..4
+range(0, 4, 1);
+// [0, 1, 2, 3, 4]
+
+// Generate numbers range 1..10 with step of 2
+range(1, 10, 2);
+// [1, 3, 5, 7, 9]
+
+// Generate the alphabet using Array.from making use of it being ordered as a sequence
+range('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x));
+// ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
+
+ +

数组去重合并

+ +
function combine(){
+    let arr = [].concat.apply([], arguments);  //没有去重复的新数组
+    return Array.from(new Set(arr));
+}
+
+var m = [1, 2, 2], n = [2,3,3];
+console.log(combine(m,n));                     // [1, 2, 3]
+ +

Polyfill

+ +

ECMA-262 第六版标准中添加了 Array.from 。有些实现中可能尚未包括在其中。你可以通过在脚本前添加如下内容作为替代方法,以使用未原生支持的 Array.from 方法。该算法按照 ECMA-262 第六版中的规范实现,并假定 ObjectTypeError 有其本身的值, callback.call 对应 {{jsxref("Function.prototype.call")}} 。此外,鉴于无法使用 Polyfill 实现真正的的迭代器,该实现不支持规范中定义的泛型可迭代元素。

+ +
// Production steps of ECMA-262, Edition 6, 22.1.2.1
+if (!Array.from) {
+  Array.from = (function () {
+    var toStr = Object.prototype.toString;
+    var isCallable = function (fn) {
+      return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
+    };
+    var toInteger = function (value) {
+      var number = Number(value);
+      if (isNaN(number)) { return 0; }
+      if (number === 0 || !isFinite(number)) { return number; }
+      return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
+    };
+    var maxSafeInteger = Math.pow(2, 53) - 1;
+    var toLength = function (value) {
+      var len = toInteger(value);
+      return Math.min(Math.max(len, 0), maxSafeInteger);
+    };
+
+    // The length property of the from method is 1.
+    return function from(arrayLike/*, mapFn, thisArg */) {
+      // 1. Let C be the this value.
+      var C = this;
+
+      // 2. Let items be ToObject(arrayLike).
+      var items = Object(arrayLike);
+
+      // 3. ReturnIfAbrupt(items).
+      if (arrayLike == null) {
+        throw new TypeError("Array.from requires an array-like object - not null or undefined");
+      }
+
+      // 4. If mapfn is undefined, then let mapping be false.
+      var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
+      var T;
+      if (typeof mapFn !== 'undefined') {
+        // 5. else
+        // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
+        if (!isCallable(mapFn)) {
+          throw new TypeError('Array.from: when provided, the second argument must be a function');
+        }
+
+        // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
+        if (arguments.length > 2) {
+          T = arguments[2];
+        }
+      }
+
+      // 10. Let lenValue be Get(items, "length").
+      // 11. Let len be ToLength(lenValue).
+      var len = toLength(items.length);
+
+      // 13. If IsConstructor(C) is true, then
+      // 13. a. Let A be the result of calling the [[Construct]] internal method
+      // of C with an argument list containing the single item len.
+      // 14. a. Else, Let A be ArrayCreate(len).
+      var A = isCallable(C) ? Object(new C(len)) : new Array(len);
+
+      // 16. Let k be 0.
+      var k = 0;
+      // 17. Repeat, while k < len… (also steps a - h)
+      var kValue;
+      while (k < len) {
+        kValue = items[k];
+        if (mapFn) {
+          A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
+        } else {
+          A[k] = kValue;
+        }
+        k += 1;
+      }
+      // 18. Let putStatus be Put(A, "length", len, true).
+      A.length = len;
+      // 20. Return A.
+      return A;
+    };
+  }());
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-array.from', 'Array.from')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-array.from', 'Array.from')}}{{Spec2('ES2015')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.from")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/includes/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/includes/index.html new file mode 100644 index 0000000000..183d9978b3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/includes/index.html @@ -0,0 +1,185 @@ +--- +title: Array.prototype.includes() +slug: Web/JavaScript/Reference/Global_Objects/Array/includes +tags: + - Array + - ECMAScript 2016 + - JavaScript + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/includes +--- +
{{JSRef}} 
+ +

includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。

+ +
{{EmbedInteractiveExample("pages/js/array-includes.html")}}
+ + + +

语法

+ +
arr.includes(valueToFind[fromIndex])
+ +

参数

+ +
+
valueToFind
+
+

需要查找的元素值。

+ +
+

Note:  使用 includes()比较字符串和字符时是区分大小写。

+
+
+
fromIndex {{optional_inline}}
+
fromIndex 索引处开始查找 valueToFind。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜 (即使从末尾开始往前跳 fromIndex 的绝对值个索引,然后往后搜寻)。默认为 0。
+
+ +

返回值

+ +

A {{jsxref("Boolean")}} which is true if the value valueToFind is found within the array (or the part of the array indicated by the index fromIndex, if specified). Values of zero are all considered to be equal regardless of sign (that is, -0 is considered to be equal to both 0 and +0), but false is not considered to be the same as 0.

+ +

返回一个布尔值 {{jsxref("Boolean")}} ,如果在数组中找到了(如果传入了 fromIndex ,表示在 fromIndex 指定的索引范围中找到了)则返回 true 。

+ +
+

Note: Technically speaking, includes() uses the sameValueZero algorithm to determine whether the given element is found.

+
+ +

示例

+ +
[1, 2, 3].includes(2);     // true
+[1, 2, 3].includes(4);     // false
+[1, 2, 3].includes(3, 3);  // false
+[1, 2, 3].includes(3, -1); // true
+[1, 2, NaN].includes(NaN); // true
+
+ +

fromIndex 大于等于数组长度

+ +

如果 fromIndex 大于等于数组的长度,则会返回 false,且该数组不会被搜索。

+ +
var arr = ['a', 'b', 'c'];
+
+arr.includes('c', 3);   // false
+arr.includes('c', 100); // false
+ +

计算出的索引小于 0

+ +

如果 fromIndex 为负值,计算出的索引将作为开始搜索searchElement的位置。如果计算出的索引小于 0,则整个数组都会被搜索。

+ +
// array length is 3
+// fromIndex is -100
+// computed index is 3 + (-100) = -97
+
+var arr = ['a', 'b', 'c'];
+
+arr.includes('a', -100); // true
+arr.includes('b', -100); // true
+arr.includes('c', -100); // true
+arr.includes('a', -2); // false
+ +

作为通用方法的 includes()

+ +

includes() 方法有意设计为通用方法。它不要求this值是数组对象,所以它可以被用于其他类型的对象 (比如类数组对象)。下面的例子展示了 在函数的 arguments 对象上调用的 includes() 方法。

+ +
(function() {
+  console.log([].includes.call(arguments, 'a')); // true
+  console.log([].includes.call(arguments, 'd')); // false
+})('a','b','c');
+ +

Polyfill

+ +
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
+if (!Array.prototype.includes) {
+  Object.defineProperty(Array.prototype, 'includes', {
+    value: function(valueToFind, fromIndex) {
+
+      if (this == null) {
+        throw new TypeError('"this" is null or not defined');
+      }
+
+      // 1. Let O be ? ToObject(this value).
+      var o = Object(this);
+
+      // 2. Let len be ? ToLength(? Get(O, "length")).
+      var len = o.length >>> 0;
+
+      // 3. If len is 0, return false.
+      if (len === 0) {
+        return false;
+      }
+
+      // 4. Let n be ? ToInteger(fromIndex).
+      //    (If fromIndex is undefined, this step produces the value 0.)
+      var n = fromIndex | 0;
+
+      // 5. If n ≥ 0, then
+      //  a. Let k be n.
+      // 6. Else n < 0,
+      //  a. Let k be len + n.
+      //  b. If k < 0, let k be 0.
+      var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
+
+      function sameValueZero(x, y) {
+        return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
+      }
+
+      // 7. Repeat, while k < len
+      while (k < len) {
+        // a. Let elementK be the result of ? Get(O, ! ToString(k)).
+        // b. If SameValueZero(valueToFind, elementK) is true, return true.
+        if (sameValueZero(o[k], valueToFind)) {
+          return true;
+        }
+        // c. Increase k by 1.
+        k++;
+      }
+
+      // 8. Return false
+      return false;
+    }
+  });
+}
+
+
+ +

如果你需要支持那些不支持Object.defineProperty的废弃JavaScript 引擎,你最好不要 polyfill Array.prototype 方法,因为你不能使它们不可枚举。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES7', '#sec-array.prototype.includes', 'Array.prototype.includes')}}{{Spec2('ES7')}}Initial definition.
{{SpecName('ESDraft', '#sec-array.prototype.includes', 'Array.prototype.includes')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.includes")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/index.html new file mode 100644 index 0000000000..b8c665f147 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/index.html @@ -0,0 +1,445 @@ +--- +title: Array +slug: Web/JavaScript/Reference/Global_Objects/Array +tags: + - JavaScript + - 二维数组 + - 全局对象 + - 参考手册 + - 数组 +translation_of: Web/JavaScript/Reference/Global_Objects/Array +--- +
{{JSRef}}
+ +
+ +

JavaScript的 Array 对象是用于构造数组的全局对象,数组是类似于列表的高阶对象。

+ +

创建数组

+ +
var fruits = ['Apple', 'Banana'];
+
+console.log(fruits.length);
+// 2
+
+ +

通过索引访问数组元素

+ +
var first = fruits[0];
+// Apple
+
+var last = fruits[fruits.length - 1];
+// Banana
+ +

遍历数组

+ +
fruits.forEach(function (item, index, array) {
+    console.log(item, index);
+});
+// Apple 0
+// Banana 1
+ +

添加元素到数组的末尾

+ +
var newLength = fruits.push('Orange');
+// newLength:3; fruits: ["Apple", "Banana", "Orange"]
+ +

删除数组末尾的元素

+ +
var last = fruits.pop(); // remove Orange (from the end)
+// last: "Orange"; fruits: ["Apple", "Banana"];
+ +

删除数组最前面(头部)的元素

+ +
var first = fruits.shift(); // remove Apple from the front
+// first: "Apple"; fruits: ["Banana"];
+ +

添加元素到数组的头部

+ +
var newLength = fruits.unshift('Strawberry') // add to the front
+// ["Strawberry", "Banana"];
+
+ +

找出某个元素在数组中的索引

+ +
fruits.push('Mango');
+// ["Strawberry", "Banana", "Mango"]
+
+var pos = fruits.indexOf('Banana');
+// 1
+ +

通过索引删除某个元素

+ +
var removedItem = fruits.splice(pos, 1); // this is how to remove an item
+
+// ["Strawberry", "Mango"]
+ +

从一个索引位置删除多个元素

+ +
var vegetables = ['Cabbage', 'Turnip', 'Radish', 'Carrot'];
+console.log(vegetables);
+// ["Cabbage", "Turnip", "Radish", "Carrot"]
+
+var pos = 1, n = 2;
+
+var removedItems = vegetables.splice(pos, n);
+// this is how to remove items, n defines the number of items to be removed,
+// from that position(pos) onward to the end of array.
+
+console.log(vegetables);
+// ["Cabbage", "Carrot"] (the original array is changed)
+
+console.log(removedItems);
+// ["Turnip", "Radish"]
+ +

复制一个数组

+ +
var shallowCopy = fruits.slice(); // this is how to make a copy
+// ["Strawberry", "Mango"]
+ +

语法

+ +
[element0, element1, ..., elementN]
+new Array(element0, element1[, ...[, elementN]])
+new Array(arrayLength)
+
+ +
+
+

参数

+
+
elementN
+
Array 构造器会根据给定的元素创建一个 JavaScript 数组,但是当仅有一个参数且为数字时除外(详见下面的 arrayLength 参数)。注意,后面这种情况仅适用于用 Array 构造器创建数组,而不适用于用方括号创建的数组字面量。
+
arrayLength
+
一个范围在 0 到 232-1 之间的整数,此时将返回一个 length 的值等于 arrayLength 的数组对象(言外之意就是该数组此时并没有包含任何实际的元素,不能理所当然地认为它包含 arrayLength 个值为 undefined 的元素)。如果传入的参数不是有效值,则会抛出 {{jsxref("RangeError")}} 异常。
+
+ +

描述

+ +

数组是一种类列表对象,它的原型中提供了遍历和修改元素的相关操作。JavaScript 数组的长度和元素类型都是非固定的。因为数组的长度可随时改变,并且其数据在内存中也可以不连续,所以 JavaScript 数组不一定是密集型的,这取决于它的使用方式。一般来说,数组的这些特性会给使用带来方便,但如果这些特性不适用于你的特定使用场景的话,可以考虑使用类型数组 {{jsxref("TypedArray")}}。

+ +

只能用整数作为数组元素的索引,而不能用字符串。后者称为关联数组。使用非整数并通过方括号点号来访问或设置数组元素时,所操作的并不是数组列表中的元素,而是数组对象的属性集合上的变量。数组对象的属性和数组元素列表是分开存储的,并且数组的遍历和修改操作也不能作用于这些命名属性。

+ +

访问数组元素

+ +

JavaScript 数组的索引是从0开始的,第一个元素的索引为0,最后一个元素的索引等于该数组的长度减1。如果指定的索引是一个无效值,JavaScript 数组并不会报错,而是会返回 undefined

+ +
var arr = ['this is the first element', 'this is the second element', 'this is the last element'];
+console.log(arr[0]);              // 打印 'this is the first element'
+console.log(arr[1]);              // 打印 'this is the second element'
+console.log(arr[arr.length - 1]); // 打印 'this is the last element'
+
+ +

虽然数组元素可以看做是数组对象的属性,就像 toString 一样,但是下面的写法是错误的,运行时会抛出 SyntaxError 异常,而原因则是使用了非法的属性名:

+ +
console.log(arr.0); // a syntax error
+
+

并不是 JavaScript 数组有什么特殊之处,而是因为在 JavaScript 中,以数字开头的属性不能用点号引用,必须用方括号。比如,如果一个对象有一个名为 3d 的属性,那么只能用方括号来引用它。下面是具体的例子:

+ +
var years = [1950, 1960, 1970, 1980, 1990, 2000, 2010];
+console.log(years.0);   // 语法错误
+console.log(years[0]);  // √
+
+
renderer.3d.setTexture(model, 'character.png');     // 语法错误
+renderer['3d'].setTexture(model, 'character.png');  // √
+
+ +

注意在 3d 那个例子中,引号是必须的。你也可以将数组的索引用引号引起来,比如 years[2] 可以写成 years['2']。 years[2] 中的 2 会被 JavaScript 解释器通过调用 toString 隐式转换成字符串。正因为这样,'2''02'years 中所引用的可能是不同位置上的元素。而下面这个例子也可能会打印 true

+ +
console.log(years['2'] != years['02']);
+
+

类似地,如果对象的属性名称是保留字(最好不要这么做!),那么就只能通过字符串的形式用方括号来访问(从 firefox 40.0a2 开始也支持用点号访问了):

+ +
var promise = {
+  'var'  : 'text',
+  'array': [1, 2, 3, 4]
+};
+
+console.log(promise['var']);
+
+ +

length 和数字下标之间的关系

+ +

JavaScript 数组的 {{jsxref("Array.length", "length")}} 属性和其数字下标之间有着紧密的联系。数组内置的几个方法(例如 {{jsxref("Array.join", "join")}}、{{jsxref("Array.slice", "slice")}}、{{jsxref("Array.indexOf", "indexOf")}} 等)都会考虑 {{jsxref("Array.length", "length")}} 的值。另外还有一些方法(例如 {{jsxref("Array.push", "push")}}、{{jsxref("Array.splice", "splice")}} 等)还会改变 {{jsxref("Array.length", "length")}} 的值。

+ +
var fruits = [];
+fruits.push('banana', 'apple', 'peach');
+
+console.log(fruits.length); // 3
+
+ +

使用一个合法的下标为数组元素赋值,并且该下标超出了当前数组的大小的时候,解释器会同时修改 {{jsxref("Array.length", "length")}} 的值:

+ +
fruits[5] = 'mango';
+console.log(fruits[5]); // 'mango'
+console.log(Object.keys(fruits));  // ['0', '1', '2', '5']
+console.log(fruits.length); // 6
+
+ +

也可以显式地给 {{jsxref("Array.length", "length")}} 赋一个更大的值:

+ +
fruits.length = 10;
+console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
+console.log(fruits.length); // 10
+
+

而为 {{jsxref("Array.length", "length")}} 赋一个更小的值则会删掉一部分元素:

+ +
fruits.length = 2;
+console.log(Object.keys(fruits)); // ['0', '1']
+console.log(fruits.length); // 2
+ +

这一节的内容在 {{jsxref("Array.length")}} 中有更详细的介绍。

+

正则匹配结果所返回的数组

+ +

使用正则表达式匹配字符串可以得到一个数组。这个数组中包含本次匹配的相关信息和匹配结果。{{jsxref("RegExp.exec")}}、{{jsxref("String.match")}}、{{jsxref("String.replace")}} 都会返回这样的数组。看下面的例子和例子下面的表格:

+ +
// 匹配1个 d 后面紧跟着至少1个 b,再后面又跟着1个 d 的子串,
+// 并且需要记住子串中匹配到的 b 和最后的 d (通过正则表达式中的分组),
+// 同时在匹配时忽略大小写
+
+myRe = /d(b+)(d)/i;
+myArray = myRe.exec("cdbBdbsbz");
+
+ +

该正则匹配返回的数组包含以下属性和元素:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性/元素说明示例
input只读属性,原始字符串cdbBdbsbz
index只读属性,匹配到的子串在原始字符串中的索引1
[0]只读元素,本次匹配到的子串dbBd
[1], ...[n]只读元素,正则表达式中所指定的分组所匹配到的子串,其数量由正则中的分组数量决定,无最大上限[1]: bB
+ [2]: d
+ +

属性

+ +
Array.length
+ +
+
Array 构造函数的 length 属性,其值为1(注意该属性为静态属性,不是数组实例的 length 属性)。
+
{{jsxref("Array.@@species", "get Array[@@species]")}}
+
返回 Array 构造函数。
+
{{jsxref("Array.prototype")}}
+
通过数组的原型对象可以为所有数组对象添加属性。
+
+ +

方法

+ +
+
{{jsxref("Array.from()")}}
+
从类数组对象或者可迭代对象中创建一个新的数组实例。
+
{{jsxref("Array.isArray()")}}
+
用来判断某个变量是否是一个数组对象。
+
{{jsxref("Array.of()")}}
+
根据一组参数来创建新的数组实例,支持任意的参数数量和类型。
+
+ +

数组实例

+ +

所有数组实例都会从 {{jsxref("Array.prototype")}} 继承属性和方法。修改 Array 的原型会影响到所有的数组实例。

+ +

属性

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype', 'Properties')}}
+ +

方法

+ +

修改器方法

+ +

{{page('zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype', 'Mutator_methods')}}

+ +

访问方法

+ +

{{page('zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype', 'Accessor_methods')}}

+ +

迭代方法

+ +

{{page('zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype', 'Iteration_methods')}}

+ +

数组泛型方法

+ +
+

泛型方法是非标准,并且已弃用,有可能不久就会移除。 需注意的是此方法同时有跨浏览器问题. 但是 Github上有可用的shim

+
+ +

有时我们会希望在字符串或其他类数组对象上使用数组所提供的方法(如函数的 {{jsxref("Functions/arguments", "arguments", "", 1)}})。此时你可以把一个字符串作为一个字符数组来看待(也就是说,把非数组以某种方式看成是一个数组)。比如,可以用下面的方法来检查变量 str 中的字符是否都是字母:

+ +
function isLetter(character) {
+  return character >= 'a' && character <= 'z';
+}
+
+if (Array.prototype.every.call(str, isLetter)) {
+  console.log("The string '" + str + "' contains only letters!");
+}
+ +

这种方法能够行得通,但不够简洁,JavaScript 1.6 中引入了一个泛型化的简写形式:

+ +
if (Array.every(str, isLetter)) {
+  console.log("The string '" + str + "' contains only letters!");
+}
+ +

{{jsxref("Global_Objects/String", "String")}} 对象也包含一些泛型方法,见: {{jsxref("Global_Objects/String", "Generics", "#String_generic_methods", 1)}}。

+ +

注意,这些并不属于 ECMAScript 标准,也不能在非 Gecko 浏览器中使用。你可以用标准方法 {{jsxref("Array.from()")}} 来替代上面的写法, from 方法可以将一个对象转换为真正的数组(虽然老的浏览器可能不支持):

+ +
if (Array.from(str).every(isLetter)) {
+  console.log("The string '" + str + "' contains only letters!");
+}
+ +

示例

+ +

创建数组

+ +

下面这个例子创建了一个长度为 0 的数组 msgArray,然后给 msgArray[0] 和 msgArray[99] 赋值,从而导致数组长度变为了 100。

+ +
var msgArray = [];
+msgArray[0] = 'Hello';
+msgArray[99] = 'world';
+
+if (msgArray.length === 100) {
+  console.log('The length is 100.');
+}
+ +

创建二维数组

+ +

下面的例子创建了一个代表国际象棋棋盘的二维数组,然后将 (6, 4) 上的 Pawn (卒)拷贝到 (4, 4) 位置,而原本 (6, 4) 位置则被设置为空格。

+ +
var board = [
+  ['R','N','B','Q','K','B','N','R'],
+  ['P','P','P','P','P','P','P','P'],
+  [' ',' ',' ',' ',' ',' ',' ',' '],
+  [' ',' ',' ',' ',' ',' ',' ',' '],
+  [' ',' ',' ',' ',' ',' ',' ',' '],
+  [' ',' ',' ',' ',' ',' ',' ',' '],
+  ['p','p','p','p','p','p','p','p'],
+  ['r','n','b','q','k','b','n','r'] ];
+
+console.log(board.join('\n') + '\n\n');
+
+// Move King's Pawn forward 2
+board[4][4] = board[6][4];
+board[6][4] = ' ';
+console.log(board.join('\n'));
+
+ +

下面是输出:

+ +
R,N,B,Q,K,B,N,R
+P,P,P,P,P,P,P,P
+ , , , , , , ,
+ , , , , , , ,
+ , , , , , , ,
+ , , , , , , ,
+p,p,p,p,p,p,p,p
+r,n,b,q,k,b,n,r
+
+R,N,B,Q,K,B,N,R
+P,P,P,P,P,P,P,P
+ , , , , , , ,
+ , , , , , , ,
+ , , , ,p, , ,
+ , , , , , , ,
+p,p,p,p, ,p,p,p
+r,n,b,q,k,b,n,r
+
+ +

用数组将一组值以表格形式显示

+ +
values = [];
+for (var x = 0; x < 10; x++){
+ values.push([
+  2 ** x,
+  2 * x ** 2
+ ])
+};
+console.table(values)
+ +

结果为:

+ +
0	1	0
+1	2	2
+2	4	8
+3	8	18
+4	16	32
+5	32	50
+6	64	72
+7	128	98
+8	256	128
+9	512	162
+ +

(第一列为索引)

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES1')}}{{Spec2('ES1')}}初始定义。
{{SpecName('ES5.1', '#sec-15.4', 'Array')}}{{Spec2('ES5.1')}}新增方法: {{jsxref("Array.isArray")}}, {{jsxref("Array.prototype.indexOf", "indexOf")}}, {{jsxref("Array.prototype.lastIndexOf", "lastIndexOf")}}, {{jsxref("Array.prototype.every", "every")}}, {{jsxref("Array.prototype.some", "some")}}, {{jsxref("Array.prototype.forEach", "forEach")}}, {{jsxref("Array.prototype.map", "map")}}, {{jsxref("Array.prototype.filter", "filter")}}, {{jsxref("Array.prototype.reduce", "reduce")}}, {{jsxref("Array.prototype.reduceRight", "reduceRight")}}
{{SpecName('ES6', '#sec-array-objects', 'Array')}}{{Spec2('ES6')}} +

新增方法:{{jsxref("Array.from")}}, {{jsxref("Array.of")}}, {{jsxref("Array.prototype.find", "find")}}, {{jsxref("Array.prototype.findIndex", "findIndex")}}, {{jsxref("Array.prototype.fill", "fill")}}, {{jsxref("Array.prototype.copyWithin", "copyWithin")}}

+
{{SpecName('ESDraft', '#sec-array-objects', 'Array')}}{{Spec2('ESDraft')}} +

新增方法:{{jsxref("Array.prototype.includes()")}}

+
+ +

浏览器兼容性

+ + + +
{{Compat("javascript.builtins.Array")}}
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/indexof/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/indexof/index.html new file mode 100644 index 0000000000..c470a8b265 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/indexof/index.html @@ -0,0 +1,197 @@ +--- +title: Array.prototype.indexOf() +slug: Web/JavaScript/Reference/Global_Objects/Array/indexOf +tags: + - JavaScript + - polyfill + - 原型 + - 参考 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/indexOf +--- +
{{JSRef}}
+ +

indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。

+ +
{{EmbedInteractiveExample("pages/js/array-indexof.html")}}
+ +
+

注意:对于String方法,请参阅 {{jsxref("String.prototype.indexOf()")}}。

+
+ +

语法

+ +
arr.indexOf(searchElement[, fromIndex])
+ +

参数

+ +
+
searchElement
+
要查找的元素
+
fromIndex {{optional_inline}}
+
开始查找的位置。如果该索引值大于或等于数组长度,意味着不会在数组里查找,返回-1。如果参数中提供的索引值是一个负值,则将其作为数组末尾的一个抵消,即-1表示从最后一个元素开始查找,-2表示从倒数第二个元素开始查找 ,以此类推。 注意:如果参数中提供的索引值是一个负值,并不改变其查找顺序,查找顺序仍然是从前向后查询数组。如果抵消后的索引值仍小于0,则整个数组都将会被查询。其默认值为0.
+
+ +

返回值

+ +

首个被找到的元素在数组中的索引位置; 若没有找到则返回 -1

+ +

描述

+ +

indexOf 使用strict equality (无论是 ===, 还是 triple-equals操作符都基于同样的方法)进行判断 searchElement与数组中包含的元素之间的关系。

+ +

示例

+ +

使用indexOf

+ +

以下例子使用indexOf方法确定多个值在数组中的位置。

+ +
var array = [2, 5, 9];
+array.indexOf(2);     // 0
+array.indexOf(7);     // -1
+array.indexOf(9, 2);  // 2
+array.indexOf(2, -1); // -1
+array.indexOf(2, -3); // 0
+
+ +

找出指定元素出现的所有位置

+ +
var indices = [];
+var array = ['a', 'b', 'a', 'c', 'a', 'd'];
+var element = 'a';
+var idx = array.indexOf(element);
+while (idx != -1) {
+  indices.push(idx);
+  idx = array.indexOf(element, idx + 1);
+}
+console.log(indices);
+// [0, 2, 4]
+
+ +

判断一个元素是否在数组里,不在则更新数组

+ +
function updateVegetablesCollection (veggies, veggie) {
+    if (veggies.indexOf(veggie) === -1) {
+        veggies.push(veggie);
+        console.log('New veggies collection is : ' + veggies);
+    } else if (veggies.indexOf(veggie) > -1) {
+        console.log(veggie + ' already exists in the veggies collection.');
+    }
+}
+
+var veggies = ['potato', 'tomato', 'chillies', 'green-pepper'];
+
+// New veggies collection is : potato,tomato,chillies,green-papper,spinach
+updateVegetablesCollection(veggies, 'spinach');
+// spinach already exists in the veggies collection.
+updateVegetablesCollection(veggies, 'spinach'); 
+ +

Polyfill

+ +

indexOf 在ECMA-262 标准 的第5版中被加入,但并非所有的浏览器都支持该方法。你可以在编写scripts时,在其开头使用以下代码,它能够允许你在没有本地支持的情况下使用indexOf方法。该算法符合ECMA-262第5版其中一项规定, 即假定 {{jsxref("Global_Objects/TypeError", "TypeError")}}和 {{jsxref("Math.abs")}} 呈现它们原有的值。

+ +
// Production steps of ECMA-262, Edition 5, 15.4.4.14
+// Reference: http://es5.github.io/#x15.4.4.14
+if (!Array.prototype.indexOf) {
+  Array.prototype.indexOf = function(searchElement, fromIndex) {
+
+    var k;
+
+    // 1. Let O be the result of calling ToObject passing
+    //    the this value as the argument.
+    if (this == null) {
+      throw new TypeError('"this" is null or not defined');
+    }
+
+    var O = Object(this);
+
+    // 2. Let lenValue be the result of calling the Get
+    //    internal method of O with the argument "length".
+    // 3. Let len be ToUint32(lenValue).
+    var len = O.length >>> 0;
+
+    // 4. If len is 0, return -1.
+    if (len === 0) {
+      return -1;
+    }
+
+    // 5. If argument fromIndex was passed let n be
+    //    ToInteger(fromIndex); else let n be 0.
+    var n = +fromIndex || 0;
+
+    if (Math.abs(n) === Infinity) {
+      n = 0;
+    }
+
+    // 6. If n >= len, return -1.
+    if (n >= len) {
+      return -1;
+    }
+
+    // 7. If n >= 0, then Let k be n.
+    // 8. Else, n<0, Let k be len - abs(n).
+    //    If k is less than 0, then let k be 0.
+    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
+
+    // 9. Repeat, while k < len
+    while (k < len) {
+      // a. Let Pk be ToString(k).
+      //   This is implicit for LHS operands of the in operator
+      // b. Let kPresent be the result of calling the
+      //    HasProperty internal method of O with argument Pk.
+      //   This step can be combined with c
+      // c. If kPresent is true, then
+      //    i.  Let elementK be the result of calling the Get
+      //        internal method of O with the argument ToString(k).
+      //   ii.  Let same be the result of applying the
+      //        Strict Equality Comparison Algorithm to
+      //        searchElement and elementK.
+      //  iii.  If same is true, return k.
+      if (k in O && O[k] === searchElement) {
+        return k;
+      }
+      k++;
+    }
+    return -1;
+  };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.4.4.14', 'Array.prototype.indexOf')}}{{Spec2('ES5.1')}}Initial definition.
+ Implemented in JavaScript 1.6
{{SpecName('ES6', '#sec-array.prototype.indexof', 'Array.prototype.indexOf')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.indexOf")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/isarray/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/isarray/index.html new file mode 100644 index 0000000000..817312bc5c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/isarray/index.html @@ -0,0 +1,140 @@ +--- +title: Array.isArray() +slug: Web/JavaScript/Reference/Global_Objects/Array/isArray +tags: + - ECMAScript5 + - JavaScript + - 'brush: js' + - class= + - polyfill + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/isArray +--- +
{{JSRef}}
+ +

Array.isArray() 用于确定传递的值是否是一个 {{jsxref("Array")}}。

+ +
Array.isArray([1, 2, 3]);
+// true
+Array.isArray({foo: 123});
+// false
+Array.isArray("foobar");
+// false
+Array.isArray(undefined);
+// false
+
+ +

语法

+ +
Array.isArray(obj)
+ +

参数

+ +
+
obj
+
需要检测的值。
+
+ +

返回值

+ +

如果值是 {{jsxref("Array")}},则为true; 否则为false。

+ +

描述

+ +

如果对象是 {{jsxref("Array")}} ,则返回true,否则为false。

+ +

有关更多详细信息,请参阅文章严格判定JavaScript对象是否为数组

+ +

See the article “Determining with absolute accuracy whether or not a JavaScript object is an array” for more details. Given a {{jsxref("TypedArray")}} instance, false is always returned.

+ +

示例

+ +
// 下面的函数调用都返回 true
+Array.isArray([]);
+Array.isArray([1]);
+Array.isArray(new Array());
+Array.isArray(new Array('a', 'b', 'c', 'd'))
+// 鲜为人知的事实:其实 Array.prototype 也是一个数组。
+Array.isArray(Array.prototype);
+
+// 下面的函数调用都返回 false
+Array.isArray();
+Array.isArray({});
+Array.isArray(null);
+Array.isArray(undefined);
+Array.isArray(17);
+Array.isArray('Array');
+Array.isArray(true);
+Array.isArray(false);
+Array.isArray(new Uint8Array(32))
+Array.isArray({ __proto__: Array.prototype });
+
+ +

instanceof 和 isArray

+ +

当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.

+ +
var iframe = document.createElement('iframe');
+document.body.appendChild(iframe);
+xArray = window.frames[window.frames.length-1].Array;
+var arr = new xArray(1,2,3); // [1,2,3]
+
+// Correctly checking for Array
+Array.isArray(arr);  // true
+// Considered harmful, because doesn't work though iframes
+arr instanceof Array; // false
+ +

Polyfill

+ +

假如不存在 Array.isArray(),则在其他代码之前运行下面的代码将创建该方法。

+ +
if (!Array.isArray) {
+  Array.isArray = function(arg) {
+    return Object.prototype.toString.call(arg) === '[object Array]';
+  };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.4.3.2', 'Array.isArray')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.8.5.
{{SpecName('ES6', '#sec-array.isarray', 'Array.isArray')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.isarray', 'Array.isArray')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.isArray")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/join/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/join/index.html new file mode 100644 index 0000000000..c40b87ebed --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/join/index.html @@ -0,0 +1,111 @@ +--- +title: Array.prototype.join() +slug: Web/JavaScript/Reference/Global_Objects/Array/join +tags: + - Array + - Array.prototype.join() + - join() + - separator +translation_of: Web/JavaScript/Reference/Global_Objects/Array/join +--- +
{{JSRef}}
+ +

join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。

+ +
{{EmbedInteractiveExample("pages/js/array-join.html")}}
+ +

语法

+ +
arr.join([separator])
+ +

参数

+ +
+
separator {{optional_inline}}
+
指定一个字符串来分隔数组的每个元素。如果需要,将分隔符转换为字符串。如果缺省该值,数组元素用逗号(,)分隔。如果separator是空字符串(""),则所有元素之间都没有任何字符。
+
+

返回值

+
+
一个所有数组元素连接的字符串。如果 arr.length 为0,则返回空字符串。
+
+ +

描述

+ +

所有的数组元素被转换成字符串,再用一个分隔符将这些字符串连接起来。

+ +
+

如果一个元素为 undefined 或 null,它会被转换为空字符串。

+
+ +

示例

+ +

使用四种不同的分隔符连接数组元素

+ +

下例首先创建了一个数组 a,包含有三个元素,然后用四种不同的分隔符连接所有数组元素。首先是默认的分隔符逗号,然后是一个逗号加空格,接下来是一个加号前后加空格,最后是一个空字符串。

+ +
var a = ['Wind', 'Rain', 'Fire'];
+var myVar1 = a.join();      // myVar1的值变为"Wind,Rain,Fire"
+var myVar2 = a.join(', ');  // myVar2的值变为"Wind, Rain, Fire"
+var myVar3 = a.join(' + '); // myVar3的值变为"Wind + Rain + Fire"
+var myVar4 = a.join('');    // myVar4的值变为"WindRainFire"
+
+ +

连接类数组对象

+ +

下面的示例将连接类数组对象(arguments),通过在Array.prototype.join上调用{{jsxref("Function.prototype.call")}}。

+ +
function f(a, b, c) {
+  var s = Array.prototype.join.call(arguments);
+  console.log(s); // '1,a,true'
+}
+f(1, 'a', true);
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.4.4.5', 'Array.prototype.join')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype.join', 'Array.prototype.join')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.join', 'Array.prototype.join')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.join")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/keys/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/keys/index.html new file mode 100644 index 0000000000..6da9228ed2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/keys/index.html @@ -0,0 +1,77 @@ +--- +title: Array.prototype.keys() +slug: Web/JavaScript/Reference/Global_Objects/Array/keys +tags: + - Array + - ECMAScript 2015 + - Iterator + - JavaScript + - Method + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Array/keys +--- +
{{JSRef}}
+ +

 keys() 方法返回一个包含数组中每个索引键的Array Iterator对象。

+ +
{{EmbedInteractiveExample("pages/js/array-keys.html")}}
+ +

语法

+ +
arr.keys()
+
+ +

返回值 

+ +

一个新的 {{jsxref("Array")}} 迭代器对象。

+ +

示例

+ +

索引迭代器会包含那些没有对应元素的索引

+ +
var arr = ["a", , "c"];
+var sparseKeys = Object.keys(arr);
+var denseKeys = [...arr.keys()];
+console.log(sparseKeys); // ['0', '2']
+console.log(denseKeys);  // [0, 1, 2]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-array.prototype.keys', 'Array.prototype.keys')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-array.prototype.keys', 'Array.prototype.keys')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.keys")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/lastindexof/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/lastindexof/index.html new file mode 100644 index 0000000000..51cf89a71f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/lastindexof/index.html @@ -0,0 +1,176 @@ +--- +title: Array.prototype.lastIndexOf() +slug: Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf +translation_of: Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf +--- +
{{JSRef("Global_Objects", "Array")}}
+ +

概述

+ +

lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。

+ +
{{EmbedInteractiveExample("pages/js/array-lastindexof.html")}}
+ +

语法

+ +
arr.lastIndexOf(searchElement[, fromIndex])
+ +

参数

+ +
+
searchElement
+
被查找的元素。
+
fromIndex {{optional_inline}}
+
从此位置开始逆向查找。默认为数组的长度减 1(arr.length - 1),即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找。
+
+

返回值

+ +

数组中该元素最后一次出现的索引,如未找到返回-1。

+
+
+ +

描述

+ +

lastIndexOf 使用严格相等(strict equality,即 ===)比较 searchElement 和数组中的元素。

+ +

示例

+ +

例子:使用 lastIndexOf

+ +

下例使用 lastIndexOf 定位数组中的值。

+ +
var array = [2, 5, 9, 2];
+var index = array.lastIndexOf(2);
+// index is 3
+index = array.lastIndexOf(7);
+// index is -1
+index = array.lastIndexOf(2, 3);
+// index is 3
+index = array.lastIndexOf(2, 2);
+// index is 0
+index = array.lastIndexOf(2, -2);
+// index is 0
+index = array.lastIndexOf(2, -1);
+// index is 3
+
+ +

例子:查找所有元素

+ +

下例使用 lastIndexOf 查找到一个元素在数组中所有的索引(下标),并使用 {{jsxref("Array.push", "push")}} 将所有添加到另一个数组中。

+ +
var indices = [];
+var array = ['a', 'b', 'a', 'c', 'a', 'd'];
+var element = 'a';
+var idx = array.lastIndexOf(element);
+
+while (idx != -1) {
+  indices.push(idx);
+  idx = (idx > 0 ? array.lastIndexOf(element, idx - 1) : -1);
+}
+
+console.log(indices);
+// [4, 2, 0];
+
+
+ +

注意,我们要单独处理idx==0时的情况,因为如果是第一个元素,忽略了fromIndex参数则第一个元素总会被查找。这不同于{{jsxref("Array.prototype.indexOf", "indexOf")}}方法

+ +

注:原英文是针对使用三元操作符语句的作用进行说明的:
+ idx = (idx > 0 ? array.lastIndexOf(element, idx - 1) : -1);
+ idx > 0时,才进入lastIndexOf由后往前移一位进行倒查找;如果idx == 0则直接设置idx = -1,循环while (idx != -1)就结束了。
+  

+ +

兼容旧环境(Polyfill)

+ +

lastIndexOf 在 ECMA-262 标准第 5 版被添加。因此它在不兼容该标准的浏览器中可能不被支持。你可以把下面代码添加到脚本中来使那些没有实现该方法的实现环境支持该方法。该算法是被 ECMA-262 第 5 版指定的。假定 {{jsxref("Global_Objects/Object", "Object")}}、{{jsxref("Global_Objects/TypeError", "TypeError")}}、{{jsxref("Global_Objects/Number", "Number")}}、{{jsxref("Math.floor")}}、{{jsxref("Math.abs")}},以及 {{jsxref("Math.min")}} 拥有其初始值。

+ +
if (!Array.prototype.lastIndexOf) {
+  Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) {
+    'use strict';
+
+    if (this === void 0 || this === null) {
+      throw new TypeError();
+    }
+
+    var n, k,
+        t = Object(this),
+        len = t.length >>> 0;
+    if (len === 0) {
+      return -1;
+    }
+
+    n = len - 1;
+    if (arguments.length > 1) {
+      n = Number(arguments[1]);
+      if (n != n) {
+        n = 0;
+      }
+      else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) {
+        n = (n > 0 || -1) * Math.floor(Math.abs(n));
+      }
+    }
+
+    for (k = n >= 0
+          ? Math.min(n, len - 1)
+          : len - Math.abs(n); k >= 0; k--) {
+      if (k in t && t[k] === searchElement) {
+        return k;
+      }
+    }
+    return -1;
+  };
+}
+
+
+ +

另外,该实现是为了绝对兼容 Firefox 和 the SpiderMonkey JavaScript 引擎中的 lastIndexOf,包括了几种临界情况。如果你要在实际应用中使用该实现,可以忽略这些临界情况,从而简化 fromIndex 的计算。

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.4.4.15', 'Array.prototype.lastIndexOf')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.6.
{{SpecName('ES6', '#sec-array.prototype.lastindexof', 'Array.prototype.lastIndexOf')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.lastindexof', 'Array.prototype.lastIndexOf')}}{{Spec2('ESDraft')}}
+ + + + + + + +
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.lastIndexOf")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/length/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/length/index.html new file mode 100644 index 0000000000..7b126495fb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/length/index.html @@ -0,0 +1,149 @@ +--- +title: Array.length +slug: Web/JavaScript/Reference/Global_Objects/Array/length +tags: + - JavaScript + - 参考 + - 属性 + - 数组 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/length +--- +

{{JSRef}}

+ +

lengthArray的实例属性。返回或设置一个数组中的元素个数。该值是一个无符号 32-bit 整数,并且总是大于数组最高项的下标。

+ +
{{EmbedInteractiveExample("pages/js/array-length.html")}}
+ +

描述

+ +

length 属性的值是一个 0 到 232-1 的整数。

+ +
var namelistA = new Array(4294967296); // 2的32次方 = 4294967296
+var namelistC = new Array(-100) // 负号
+
+console.log(namelistA.length); // RangeError: 无效数组长度
+console.log(namelistC.length); // RangeError: 无效数组长度
+
+
+
+var namelistB = [];
+namelistB.length = Math.pow(2,32)-1; //set array length less than 2 to the 32nd power
+console.log(namelistB.length);
+
+// 4294967295
+
+ +

你可以设置 length 属性的值来截断任何数组。当通过改变length属性值来扩展数组时,实际元素的数目将会增加。例如:将一个拥有 2 个元素的数组的 length 属性值设为 3 时,那么这个数组将会包含3个元素,并且,第三个元素的值将会是 undefined

+ +
var arr = [1, 2, 3];
+printEntries(arr);
+
+arr.length = 5; // set array length to 5 while currently 3.
+printEntries(arr);
+
+function printEntries(arr) {
+  var goNext = true;
+  var entries = arr.entries();
+  while (goNext) {
+    var result = entries.next();
+    if (result.done !== true) {
+      console.log(result.value[1]);
+      goNext = true;
+    } else
+      goNext = false;
+  }
+  console.log('=== printed ===');
+}
+
+// 1
+// 2
+// 3
+// === printed ===
+// 1
+// 2
+// 3
+// undefined
+// undefined
+// === printed ===
+ +

但是, length 属性不一定表示数组中定义值的个数。了解更多:长度与数值下标属性之间的关系

+ +

{{js_property_attributes(1, 0, 0)}}

+ + + +

示例 

+ +

遍历数组

+ +

下面的例子中,通过数组下标遍历数组元素,并把每个元素的值修改为原值的2倍。

+ +
var numbers = [1, 2, 3, 4, 5];
+var length = numbers.length;
+for (var i = 0; i < length; i++) {
+  numbers[i] *= 2;
+}
+// 遍历后的结果 [2, 4, 6, 8, 10]
+ +

截断数组

+ +

下面的例子中,如果数组长度大于 3,则把该数组的长度截断为 3 。

+ +
var numbers = [1, 2, 3, 4, 5];
+
+if (numbers.length > 3) {
+  numbers.length = 3;
+}
+
+console.log(numbers); // [1, 2, 3]
+console.log(numbers.length); // 3
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.4.5.2', 'Array.length')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-array-instances-length', 'Array.length')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-properties-of-array-instances-length', 'Array.length')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.length")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/map/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/map/index.html new file mode 100644 index 0000000000..b00ce5df07 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/map/index.html @@ -0,0 +1,343 @@ +--- +title: Array.prototype.map() +slug: Web/JavaScript/Reference/Global_Objects/Array/map +tags: + - Array + - ECMAScript5 + - JavaScript + - Method + - Prototype + - polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/Array/map +--- +
{{JSRef}}
+ +

map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

+ +
{{EmbedInteractiveExample("pages/js/array-map.html")}}
+ + + +

语法

+ +
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
+ // Return element for new_array 
+}[, thisArg])
+ +

参数

+ +
+
callback
+
生成新数组元素的函数,使用三个参数: +
+
currentValue
+
callback 数组中正在处理的当前元素。
+
index{{optional_inline}}
+
callback 数组中正在处理的当前元素的索引。
+
array{{optional_inline}}
+
map 方法调用的数组。
+
+
+
thisArg{{optional_inline}}
+
执行 callback 函数时值被用作this
+
+ +

返回值

+ +

一个由原数组每个元素执行回调函数的结果组成的新数组。

+ +

描述

+ +

map 方法会给原数组中的每个元素都按顺序调用一次  callback 函数。callback 每次执行后的返回值(包括 {{jsxref("undefined")}})组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。

+ +

因为map生成一个新数组,当你不打算使用返回的新数组却使用map是违背设计初衷的,请用forEach或者for-of替代。你不该使用map: A)你不打算使用返回的新数组,或/且 B) 你没有从回调函数中返回值。

+ +

callback 函数会被自动传入三个参数:数组元素,元素索引,原数组本身。

+ +

如果 thisArg 参数提供给map,则会被用作回调函数的this值。否则{{jsxref("undefined")}}会被用作回调函数的this值。this的值最终相对于callback函数的可观察性是依据the usual rules for determining the this seen by a function决定的

+ +

map 不修改调用它的原数组本身(当然可以在 callback 执行时改变原数组)

+ +

map 方法处理数组元素的范围是在 callback 方法第一次调用之前就已经确定了。调用map方法之后追加的数组元素不会被callback访问。如果存在的数组元素改变了,那么传给callback的值是map访问该元素时的值。在map函数调用后但在访问该元素前,该元素被删除的话,则无法被访问到。

+ +

根据规范中定义的算法,如果被map调用的数组是离散的,新数组将也是离散的保持相同的索引为空。

+ +

示例

+ +

求数组中每个元素的平方根

+ +

下面的代码创建了一个新数组,值为原数组中对应数字的平方根。

+ +
var numbers = [1, 4, 9];
+var roots = numbers.map(Math.sqrt);
+// roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9]
+ +

使用 map 重新格式化数组中的对象

+ +

以下代码使用一个包含对象的数组来重新创建一个格式化后的数组。

+ +
var kvArray = [{key: 1, value: 10},
+               {key: 2, value: 20},
+               {key: 3, value: 30}];
+
+var reformattedArray = kvArray.map(function(obj) {
+   var rObj = {};
+   rObj[obj.key] = obj.value;
+   return rObj;
+});
+
+// reformattedArray 数组为: [{1: 10}, {2: 20}, {3: 30}],
+
+// kvArray 数组未被修改:
+// [{key: 1, value: 10},
+//  {key: 2, value: 20},
+//  {key: 3, value: 30}]
+
+ +

使用一个包含一个参数的函数来mapping(构建)一个数字数组

+ +

下面的代码表示了当函数需要一个参数时map的工作方式。当map循环遍历原始数组时,这个参数会自动被分配成数组中对应的每个元素。

+ +
var numbers = [1, 4, 9];
+var doubles = numbers.map(function(num) {
+  return num * 2;
+});
+
+// doubles数组的值为: [2, 8, 18]
+// numbers数组未被修改: [1, 4, 9]
+ +

一般的map 方法

+ +

下面的例子演示如何在一个 {{jsxref("String")}}  上使用 map 方法获取字符串中每个字符所对应的 ASCII 码组成的数组:

+ +
var map = Array.prototype.map
+var a = map.call("Hello World", function(x) {
+  return x.charCodeAt(0);
+})
+// a的值为[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
+
+ +

querySelectorAll 应用

+ +

下面代码展示了如何去遍历用 querySelectorAll 得到的动态对象集合。在这里,我们获得了文档里所有选中的选项,并将其打印:

+ +
var elems = document.querySelectorAll('select option:checked');
+var values = Array.prototype.map.call(elems, function(obj) {
+  return obj.value;
+});
+
+ +

使用技巧案例

+ +

(原文地址)

+ +

通常情况下,map 方法中的 callback 函数只需要接受一个参数,就是正在被遍历的数组元素本身。但这并不意味着 map 只给 callback 传了一个参数。这个思维惯性可能会让我们犯一个很容易犯的错误。

+ +

考虑下例:

+ +
["1", "2", "3"].map(parseInt);
+ +

我们期望输出 [1, 2, 3], 而实际结果是 [1, NaN, NaN].

+ +

parseInt 经常被带着一个参数使用, 但是这里接受两个。第一个参数是一个表达式而第二个是callback function的基, Array.prototype.map 传递3个参数:

+ + + +

第三个参数被parseInt忽视了, but not the second one, 但不是第二个。因此可能出现混淆。下面是迭代步骤的简明示例:

+ +
// parseInt(string, radix) -> map(parseInt(value, index))
+/*  first iteration (index is 0): */ parseInt("1", 0); // 1
+/* second iteration (index is 1): */ parseInt("2", 1); // NaN
+/*  third iteration (index is 2): */ parseInt("3", 2); // NaN
+ +

下面让我们来讨论解决方案:

+ +
function returnInt(element) {
+  return parseInt(element, 10);
+}
+
+['1', '2', '3'].map(returnInt); // [1, 2, 3]
+// Actual result is an array of numbers (as expected)
+
+// Same as above, but using the concise arrow function syntax
+['1', '2', '3'].map( str => parseInt(str) );
+
+// A simpler way to achieve the above, while avoiding the "gotcha":
+['1', '2', '3'].map(Number); // [1, 2, 3]
+
+// But unlike parseInt(), Number() will also return a float or (resolved) exponential notation:
+['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300]
+// For comparison, if we use parseInt() on the array above:
+['1.1', '2.2e2', '3e300'].map( str => parseInt(str) ); // [1, 2, 3]
+ +

一个map方法调用 parseInt 作为一个参数的等效输出运行如下:

+ +
var xs = ['10', '10', '10'];
+
+xs = xs.map(parseInt);
+
+console.log(xs);  // 输出结果为(3) [10, NaN, 2]
+// Actual result of 10,NaN,2 may be unexpected based on the above description.
+ +

Mapping 含 undefined的数组

+ +

当返回undefined 或没有返回任何内容时:

+ +
var numbers = [1, 2, 3, 4];
+var filteredNumbers = numbers.map(function(num, index) {
+  if(index < 3) {
+     return num;
+  }
+});
+//index goes from 0,so the filterNumbers are 1,2,3 and undefined.
+// filteredNumbers is [1, 2, 3, undefined]
+// numbers is still [1, 2, 3, 4]
+ +

Polyfill

+ +

map was added to the ECMA-262 standard in the 5th edition; as such it may not be present in all implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of map in implementations which do not natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming {{jsxref("Object")}}, {{jsxref("TypeError")}}, and {{jsxref("Array")}} have their original values and that callback.call evaluates to the original value of {{jsxref("Function.prototype.call")}}.

+ +
// Production steps of ECMA-262, Edition 5, 15.4.4.19
+// Reference: http://es5.github.io/#x15.4.4.19
+if (!Array.prototype.map) {
+
+  Array.prototype.map = function(callback/*, thisArg*/) {
+
+    var T, A, k;
+
+    if (this == null) {
+      throw new TypeError('this is null or not defined');
+    }
+
+    // 1. Let O be the result of calling ToObject passing the |this|
+    //    value as the argument.
+    var O = Object(this);
+
+    // 2. Let lenValue be the result of calling the Get internal
+    //    method of O with the argument "length".
+    // 3. Let len be ToUint32(lenValue).
+    var len = O.length >>> 0;
+
+    // 4. If IsCallable(callback) is false, throw a TypeError exception.
+    // See: http://es5.github.com/#x9.11
+    if (typeof callback !== 'function') {
+      throw new TypeError(callback + ' is not a function');
+    }
+
+    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+    if (arguments.length > 1) {
+      T = arguments[1];
+    }
+
+    // 6. Let A be a new array created as if by the expression new Array(len)
+    //    where Array is the standard built-in constructor with that name and
+    //    len is the value of len.
+    A = new Array(len);
+
+    // 7. Let k be 0
+    k = 0;
+
+    // 8. Repeat, while k < len
+    while (k < len) {
+
+      var kValue, mappedValue;
+
+      // a. Let Pk be ToString(k).
+      //   This is implicit for LHS operands of the in operator
+      // b. Let kPresent be the result of calling the HasProperty internal
+      //    method of O with argument Pk.
+      //   This step can be combined with c
+      // c. If kPresent is true, then
+      if (k in O) {
+
+        // i. Let kValue be the result of calling the Get internal
+        //    method of O with argument Pk.
+        kValue = O[k];
+
+        // ii. Let mappedValue be the result of calling the Call internal
+        //     method of callback with T as the this value and argument
+        //     list containing kValue, k, and O.
+        mappedValue = callback.call(T, kValue, k, O);
+
+        // iii. Call the DefineOwnProperty internal method of A with arguments
+        // Pk, Property Descriptor
+        // { Value: mappedValue,
+        //   Writable: true,
+        //   Enumerable: true,
+        //   Configurable: true },
+        // and false.
+
+        // In browsers that support Object.defineProperty, use the following:
+        // Object.defineProperty(A, k, {
+        //   value: mappedValue,
+        //   writable: true,
+        //   enumerable: true,
+        //   configurable: true
+        // });
+
+        // For best browser support, use the following:
+        A[k] = mappedValue;
+      }
+      // d. Increase k by 1.
+      k++;
+    }
+
+    // 9. return A
+    return A;
+  };
+}
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.4.4.19', 'Array.prototype.map')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.6.
{{SpecName('ES6', '#sec-array.prototype.map', 'Array.prototype.map')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.map', 'Array.prototype.map')}}{{Spec2('ESDraft')}}
+ + + + + + + +
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.map")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/observe/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/observe/index.html new file mode 100644 index 0000000000..7c2dcc8474 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/observe/index.html @@ -0,0 +1,92 @@ +--- +title: Array.observe() +slug: Web/JavaScript/Reference/Global_Objects/Array/observe +tags: + - JavaScript + - 实验性 + - 数组 + - 方法 + - 过时的 +translation_of: Archive/Web/JavaScript/Array.observe +--- +
{{JSRef}}{{obsolete_header}}
+ +

Array.observe() 方法用于异步监视数组发生的变化,类似于针对对象的 {{jsxref("Object.observe()")}} 。当数组的值发生变化时,它按发生顺序提供了一个变化流。与 Object.observe() 类似,它由如下可接受的变化类型列表["add"、"update"、"delete"、"splice"]触发。

+ +

语法

+ +
Array.observe(arr, callback)
+ +

参数

+ +
+
arr
+
用于被监视的数组
+
callback
+
每当数组发生变化时,使用如下参数调用该函数: +
+
changes
+
用于表示变化的对象数组。每个变化对象的属性如下: +
    +
  • name: 变化的属性名。
  • +
  • object: 变化后的数组。
  • +
  • type: 用于表示变化类型的字符串。其取值为"add"、"update"、"delete""splice"之一。
  • +
  • oldValue: 仅用于"update""delete"类型。变化之前的取值。
  • +
  • index: 仅用于"splice"类型。变化发生所在索引。
  • +
  • removed: 仅用于"splice"类型。被删除元素组成的数组。
  • +
  • addedCount: 仅用于"splice"类型。被添加的元素数量。
  • +
+
+
+
+
+ +

描述

+ +

每次 arr 发生任何变化时,回调函数将被调用,调用参数为所有变化按发生顺序组成的数组。

+ +
+

通过Array方法如 Array.prototype.pop( ) 触发的变化将被报告成"splice"变化,长度不变但索引赋值发生变化的将被报告成"update"变化。

+
+ +

示例

+ +

Example: Logging different change types

+ +
var arr = ['a', 'b', 'c'];
+
+Array.observe(arr, function(changes) {
+  console.log(changes);
+});
+
+arr[1] = 'B';
+// [{type: 'update', object: <arr>, name: '1', oldValue: 'b'}]
+
+arr[3] = 'd';
+// [{type: 'splice', object: <arr>, index: 3, removed: [], addedCount: 1}]
+
+arr.splice(1, 2, 'beta', 'gamma', 'delta');
+// [{type: 'splice', object: <arr>, index: 1, removed: ['B', 'c'], addedCount: 3}]
+
+ +

标准规范

+ +

Strawman proposal specification.

+ +

浏览器支持

+ +
+
+ + +

{{Compat("javascript.builtins.Array.observe")}}

+
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/of/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/of/index.html new file mode 100644 index 0000000000..4636c06bdb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/of/index.html @@ -0,0 +1,99 @@ +--- +title: Array.of() +slug: Web/JavaScript/Reference/Global_Objects/Array/of +tags: + - Array + - Array.of() + - ECMAScript 2015 + - ES 6 + - JavaScript + - polyfill + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/of +--- +
{{JSRef}}
+ +

Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。

+ +

 Array.of() 和 Array 构造函数之间的区别在于处理整数参数:Array.of(7) 创建一个具有单个元素 7 的数组,而 Array(7) 创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)。

+ +
Array.of(7);       // [7]
+Array.of(1, 2, 3); // [1, 2, 3]
+
+Array(7);          // [ , , , , , , ]
+Array(1, 2, 3);    // [1, 2, 3]
+
+ +

语法

+ +
Array.of(element0[, element1[, ...[, elementN]]])
+ +

参数

+ +
+
elementN
+
任意个参数,将按顺序成为返回数组中的元素。
+
+ +

返回值

+ +

新的 {{jsxref("Array")}} 实例。

+ +

描述

+ +

此函数是ECMAScript 2015标准的一部分。详见 Array.of 和 Array.from proposal 和 Array.of polyfill

+ +

示例

+ +
Array.of(1);         // [1]
+Array.of(1, 2, 3);   // [1, 2, 3]
+Array.of(undefined); // [undefined]
+
+ +

兼容旧环境

+ +

如果原生不支持的话,在其他代码之前执行以下代码会创建 Array.of() 。

+ +
if (!Array.of) {
+  Array.of = function() {
+    return Array.prototype.slice.call(arguments);
+  };
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-array.of', 'Array.of')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-array.of', 'Array.of')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.of")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/pop/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/pop/index.html new file mode 100644 index 0000000000..51fc625019 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/pop/index.html @@ -0,0 +1,101 @@ +--- +title: Array.prototype.pop() +slug: Web/JavaScript/Reference/Global_Objects/Array/pop +tags: + - Array + - Array.prototype.pop() + - ES5 + - ES6 + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Array/pop +--- +

{{JSRef}}

+ +

pop()方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。

+ +
{{EmbedInteractiveExample("pages/js/array-pop.html")}}
+ + + +

语法

+ +
arr.pop()
+ +

返回值

+ +

从数组中删除的元素(当数组为空时返回{{jsxref("undefined")}})。

+ +

描述

+ +

pop 方法从一个数组中删除并返回最后一个元素。

+ +

pop 方法有意具有通用性。该方法和 {{jsxref("Function.call", "call()")}} 或 {{jsxref("Function.apply", "apply()")}} 一起使用时,可应用在类似数组的对象上。pop方法根据 length属性来确定最后一个元素的位置。如果不包含length属性或length属性不能被转成一个数值,会将length置为0,并返回undefined

+ +

如果你在一个空数组上调用 pop(),它返回  {{jsxref("undefined")}}。

+ +

示例

+ +

例子: 删除掉数组的最后一个元素

+ +

下面的代码首先创建了一个拥有四个元素的数组 myFish,然后删除掉它的最后一个元素。

+ +
let myFish = ["angel", "clown", "mandarin", "surgeon"];
+
+let popped = myFish.pop();
+
+console.log(myFish);
+// ["angel", "clown", "mandarin"]
+
+console.log(popped);
+// surgeon
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.4.4.6', 'Array.prototype.pop')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-array.prototype.pop', 'Array.prototype.pop')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-array.prototype.pop', 'Array.prototype.pop')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.pop")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/prototype/index.html new file mode 100644 index 0000000000..31d65bf734 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/prototype/index.html @@ -0,0 +1,178 @@ +--- +title: Array.prototype +slug: Web/JavaScript/Reference/Global_Objects/Array/prototype +tags: + - Array.prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Array/prototype +--- +
{{JSRef}}
+ +

Array.prototype  属性表示 {{jsxref("Array")}} 构造函数的原型,并允许您向所有Array对象添加新的属性和方法。

+ +
/*
+如果JavaScript本身不提供 first() 方法,
+添加一个返回数组的第一个元素的新方法。
+*/
+
+if(!Array.prototype.first) {
+    Array.prototype.first = function() {
+        console.log(`如果JavaScript本身不提供 first() 方法,
+添加一个返回数组的第一个元素的新方法。`);
+        return this[0];
+    }
+}
+
+ +

描述

+ +

{{jsxref("Array")}}实例继承自 Array.prototype 。与所有构造函数一样,您可以更改构造函数的原型对象,以对所有 {{jsxref("Array")}} 实例进行更改。例如,可以添加新方法和属性以扩展所有Array对象。这用于 {{Glossary("Polyfill", "polyfilling")}}, 例如。

+ +

鲜为人知的事实:Array.prototype 本身也是一个 {{jsxref("Array")}}。

+ +
Array.isArray(Array.prototype);
+// true
+
+ +

{{js_property_attributes(0, 0, 0)}}

+ +

属性

+ +
+
Array.prototype.constructor
+
所有的数组实例都继承了这个属性,它的值就是 {{jsxref("Array")}},表明了所有的数组都是由 {{jsxref("Array")}} 构造出来的。
+
{{jsxref("Array.prototype.length")}}
+
上面说了,因为 Array.prototype 也是个数组,所以它也有 length 属性,这个值为 0,因为它是个空数组。
+
+ +

方法

+ +

会改变自身的方法

+ +

下面的这些方法会改变调用它们的对象自身的值:

+ +
+
{{jsxref("Array.prototype.copyWithin()")}} {{experimental_inline}}
+
在数组内部,将一段元素序列拷贝到另一段元素序列上,覆盖原有的值。
+
{{jsxref("Array.prototype.fill()")}} {{experimental_inline}}
+
将数组中指定区间的所有元素的值,都替换成某个固定的值。
+
{{jsxref("Array.prototype.pop()")}}
+
删除数组的最后一个元素,并返回这个元素。
+
{{jsxref("Array.prototype.push()")}}
+
在数组的末尾增加一个或多个元素,并返回数组的新长度。
+
{{jsxref("Array.prototype.reverse()")}}
+
颠倒数组中元素的排列顺序,即原先的第一个变为最后一个,原先的最后一个变为第一个。
+
{{jsxref("Array.prototype.shift()")}}
+
删除数组的第一个元素,并返回这个元素。
+
{{jsxref("Array.prototype.sort()")}}
+
对数组元素进行排序,并返回当前数组。
+
{{jsxref("Array.prototype.splice()")}}
+
在任意的位置给数组添加或删除任意个元素。
+
{{jsxref("Array.prototype.unshift()")}}
+
在数组的开头增加一个或多个元素,并返回数组的新长度。
+
+ +

不会改变自身的方法

+ +

下面的这些方法绝对不会改变调用它们的对象的值,只会返回一个新的数组或者返回一个其它的期望值。

+ +
+
{{jsxref("Array.prototype.concat()")}}
+
返回一个由当前数组和其它若干个数组或者若干个非数组值组合而成的新数组。
+
{{jsxref("Array.prototype.includes()")}} {{experimental_inline}}
+
判断当前数组是否包含某指定的值,如果是返回 true,否则返回 false
+
{{jsxref("Array.prototype.join()")}}
+
连接所有数组元素组成一个字符串。
+
{{jsxref("Array.prototype.slice()")}}
+
抽取当前数组中的一段元素组合成一个新数组。
+
{{jsxref("Array.prototype.toSource()")}} {{non-standard_inline}}
+
返回一个表示当前数组字面量的字符串。遮蔽了原型链上的 {{jsxref("Object.prototype.toSource()")}} 方法。
+
{{jsxref("Array.prototype.toString()")}}
+
返回一个由所有数组元素组合而成的字符串。遮蔽了原型链上的 {{jsxref("Object.prototype.toString()")}} 方法。
+
{{jsxref("Array.prototype.toLocaleString()")}}
+
返回一个由所有数组元素组合而成的本地化后的字符串。遮蔽了原型链上的 {{jsxref("Object.prototype.toLocaleString()")}} 方法。
+
{{jsxref("Array.prototype.indexOf()")}}
+
返回数组中第一个与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。
+
{{jsxref("Array.prototype.lastIndexOf()")}}
+
返回数组中最后一个(从右边数第一个)与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。
+
+ +

遍历方法

+ +

在下面的众多遍历方法中,有很多方法都需要指定一个回调函数作为参数。在每一个数组元素都分别执行完回调函数之前,数组的length属性会被缓存在某个地方,所以,如果你在回调函数中为当前数组添加了新的元素,那么那些新添加的元素是不会被遍历到的。此外,如果在回调函数中对当前数组进行了其它修改,比如改变某个元素的值或者删掉某个元素,那么随后的遍历操作可能会受到未预期的影响。总之,不要尝试在遍历过程中对原数组进行任何修改,虽然规范对这样的操作进行了详细的定义,但为了可读性和可维护性,请不要这样做。

+ +
+
{{jsxref("Array.prototype.forEach()")}}
+
为数组中的每个元素执行一次回调函数。
+
{{jsxref("Array.prototype.entries()")}} {{experimental_inline}}
+
返回一个数组迭代器对象,该迭代器会包含所有数组元素的键值对。
+
{{jsxref("Array.prototype.every()")}}
+
如果数组中的每个元素都满足测试函数,则返回 true,否则返回 false。
+
{{jsxref("Array.prototype.some()")}}
+
如果数组中至少有一个元素满足测试函数,则返回 true,否则返回 false。
+
{{jsxref("Array.prototype.filter()")}}
+
将所有在过滤函数中返回 true 的数组元素放进一个新数组中并返回。
+
{{jsxref("Array.prototype.find()")}} {{experimental_inline}}
+
找到第一个满足测试函数的元素并返回那个元素的值,如果找不到,则返回 undefined
+
{{jsxref("Array.prototype.findIndex()")}} {{experimental_inline}}
+
找到第一个满足测试函数的元素并返回那个元素的索引,如果找不到,则返回 -1
+
{{jsxref("Array.prototype.keys()")}} {{experimental_inline}}
+
返回一个数组迭代器对象,该迭代器会包含所有数组元素的键。
+
{{jsxref("Array.prototype.map()")}}
+
返回一个由回调函数的返回值组成的新数组。
+
{{jsxref("Array.prototype.reduce()")}}
+
从左到右为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。
+
{{jsxref("Array.prototype.reduceRight()")}}
+
从右到左为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。
+
{{jsxref("Array.prototype.values()")}} {{experimental_inline}}
+
返回一个数组迭代器对象,该迭代器会包含所有数组元素的值。
+
{{jsxref("Array.prototype.@@iterator()", "Array.prototype[@@iterator]()")}} {{experimental_inline}}
+
和上面的 values() 方法是同一个函数。
+
+ +

通用方法

+ +

在 JavaScript 中,很多的数组方法被故意设计成是通用的。也就是说,那些看起来像是数组的对象(类数组对象),即拥有一个 length 属性,以及对应的索引属性(也就是数字类型的属性,比如 obj[5])的非数组对象也是可以调用那些数组方法的。其中一些数组方法,比如说 {{jsxref("Array.join", "join")}} 方法,它们只会单纯的读取当前对象的 length 属性和索引属性的值,并不会尝试去改变这些属性的值。而另外一些数组方法,比如说 {{jsxref("Array.reverse", "reverse")}} 方法,它们会尝试修改那些属性的值,因此,如果当前对象是个 {{jsxref("String")}} 对象,那么这些方法在执行时就会报错,因为字符串对象的 length 属性和索引属性都是只读的。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.4.3.1', 'Array.prototype')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype', 'Array.prototype')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.prototype")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/push/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/push/index.html new file mode 100644 index 0000000000..3be7c12520 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/push/index.html @@ -0,0 +1,149 @@ +--- +title: Array.prototype.push() +slug: Web/JavaScript/Reference/Global_Objects/Array/push +tags: + - Array + - Array.prototype.push() + - JavaScript + - Method + - Prototype + - 参考 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/push +--- +
{{JSRef}}
+ +

push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。

+ +
{{EmbedInteractiveExample("pages/js/array-push.html")}}
+ + + +

语法

+ +
arr.push(element1, ..., elementN)
+
+ +

参数

+ +
+
elementN
+
被添加到数组末尾的元素。
+
+ +

返回值

+ +

当调用该方法时,新的 {{jsxref("Array.length", "length")}} 属性值将被返回。

+ +

描述

+ +

push方法将值追加到数组中。

+ +

push 方法具有通用性。该方法和 {{jsxref("Function.call", "call()")}} 或 {{jsxref("Function.apply", "apply()")}} 一起使用时,可应用在类似数组的对象上。push 方法根据 length 属性来决定从哪里开始插入给定的值。如果 length 不能被转成一个数值,则插入的元素索引为 0,包括 length 不存在时。当 length 不存在时,将会创建它。

+ +

唯一的原生类数组(array-like)对象是 {{jsxref("Global_Objects/String", "Strings")}},尽管如此,它们并不适用该方法,因为字符串是不可改变的。

+ +

示例

+ +

添加元素到数组

+ +

下面的代码创建了 sports 数组,包含两个元素,然后又把两个元素添加给它。total 变量为数组的新长度值。

+ +
var sports = ["soccer", "baseball"];
+var total = sports.push("football", "swimming");
+
+console.log(sports);
+// ["soccer", "baseball", "football", "swimming"]
+
+console.log(total);
+// 4
+ +

合并两个数组

+ +

该示例使用 {{jsxref("Function.apply", "apply()")}} 添加第二个数组的所有元素。

+ +

注意当第二个数组(如示例中的moreVegs)太大时不要使用这个方法来合并数组,因为事实上一个函数能够接受的参数个数是有限制的。具体可以参考 {{jsxref("Function.apply", "apply()")}} 。

+ +
var vegetables = ['parsnip', 'potato'];
+var moreVegs = ['celery', 'beetroot'];
+
+// 将第二个数组融合进第一个数组
+// 相当于 vegetables.push('celery', 'beetroot');
+Array.prototype.push.apply(vegetables, moreVegs);
+
+console.log(vegetables);
+// ['parsnip', 'potato', 'celery', 'beetroot']
+ +

像数组一样使用对象

+ +

如上所述,push 是特意设计为通用的,我们可以使用它来获得便利。正如下面的例子所示,Array.prototype.push 可以在一个对象上工作。 注意,我们没有创建一个数组来存储对象的集合。 相反,我们将该集合存储在对象本身上,并使用在 Array.prototype.push 上使用的 call 来调用该方法,使其认为我们正在处理数组,而它只是像平常一样运作,这要感谢 JavaScript 允许我们建立任意的执行上下文。

+ +
var obj = {
+    length: 0,
+
+    addElem: function addElem (elem) {
+        // obj.length is automatically incremented
+        // every time an element is added.
+        [].push.call(this, elem);
+    }
+};
+
+// Let's add some empty objects just to illustrate.
+obj.addElem({});
+obj.addElem({});
+console.log(obj.length);
+// → 2
+ +

注意,尽管 obj 不是数组,但是 push 方法成功地使 obj 的 length 属性增长了,就像我们处理一个实际的数组一样。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.4.4.7', 'Array.prototype.push')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype.push', 'Array.prototype.push')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.push', 'Array.prototype.push')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.push")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/reduce/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/reduce/index.html new file mode 100644 index 0000000000..75edc90a73 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/reduce/index.html @@ -0,0 +1,688 @@ +--- +title: Array.prototype.reduce() +slug: Web/JavaScript/Reference/Global_Objects/Array/Reduce +tags: + - Array + - ECMAScript 5 + - JavaScript + - Method + - Prototype + - Reduce + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Array/Reduce +--- +

{{JSRef}}

+ +

reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

+ +
{{EmbedInteractiveExample("pages/js/array-reduce.html")}}
+ + + +
+

reducer 函数接收4个参数:

+ +
    +
  1. Accumulator (acc) (累计器)
  2. +
  3. Current Value (cur) (当前值)
  4. +
  5. Current Index (idx) (当前索引)
  6. +
  7. Source Array (src) (源数组)
  8. +
+ +

您的 reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。

+
+ +

语法

+ +
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
+ +

参数

+ +
+
callback
+
执行数组中每个值 (如果没有提供 initialValue则第一个值除外)的函数,包含四个参数:
+
+
+
+ accumulator + +
+
+

累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。

+
+
currentValue
+
数组中正在处理的元素。
+
index {{optional_inline}}
+
数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始。
+
array{{optional_inline}}
+
调用reduce()的数组
+
+
+
initialValue{{optional_inline}}
+
作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
+
+ +

返回值

+ +

函数累计处理的结果

+ +

描述

+ +

reduce为数组中的每一个元素依次执行callback函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:

+ + + +

回调函数第一次执行时,accumulatorcurrentValue的取值有两种情况:如果调用reduce()时提供了initialValueaccumulator取值为initialValuecurrentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。

+ +
+

注意:如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。

+
+ +

如果数组为空且没有提供initialValue,会抛出{{jsxref("TypeError")}} 。如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行。

+ +

提供初始值通常更安全,正如下面的例子,如果没有提供initialValue,则可能有四种输出:

+ +
var maxCallback = ( acc, cur ) => Math.max( acc.x, cur.x );
+var maxCallback2 = ( max, cur ) => Math.max( max, cur );
+
+// reduce() 没有初始值
+[ { x: 2 }, { x: 22 }, { x: 42 } ].reduce( maxCallback ); // NaN
+[ { x: 2 }, { x: 22 }            ].reduce( maxCallback ); // 22
+[ { x: 2 }                       ].reduce( maxCallback ); // { x: 2 }
+[                                ].reduce( maxCallback ); // TypeError
+
+// map/reduce; 这是更好的方案,即使传入空数组或更大数组也可正常执行
+[ { x: 22 }, { x: 42 } ].map( el => el.x )
+                        .reduce( maxCallback2, -Infinity );
+
+ +

reduce() 如何运行

+ +

假如运行下段reduce()代码:

+ +
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
+  return accumulator + currentValue;
+});
+
+ +

callback 被调用四次,每次调用的参数和返回值如下表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
callbackaccumulatorcurrentValuecurrentIndexarrayreturn value
first call011[0, 1, 2, 3, 4]1
second call122[0, 1, 2, 3, 4]3
third call333[0, 1, 2, 3, 4]6
fourth call644[0, 1, 2, 3, 4]10
+ + + + + + +
+ +

reduce返回的值将是最后一次回调返回值(10)。

+ +

你还可以使用{{jsxref("Functions/Arrow_functions", "箭头函数","",1)}}来代替完整的函数。 下面的代码将产生与上面的代码相同的输出:

+ +
[0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr );
+ +

如果你打算提供一个初始值作为reduce()方法的第二个参数,以下是运行过程及结果:

+ +
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => {
+    return accumulator + currentValue
+}, 10)
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
callbackaccumulatorcurrentValuecurrentIndexarrayreturn value
first call1000[0, 1, 2, 3, 4]10
second call1011[0, 1, 2, 3, 4]11
third call1122[0, 1, 2, 3, 4]13
fourth call1333[0, 1, 2, 3, 4]16
fifth call1644[0, 1, 2, 3, 4]20
+ +

这种情况下reduce()返回的值是20

+ +

例子

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

数组里所有值的和

+ +
var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
+  return accumulator + currentValue;
+}, 0);
+// 和为 6
+ +

你也可以写成箭头函数的形式:

+ +
var total = [ 0, 1, 2, 3 ].reduce(
+  ( acc, cur ) => acc + cur,
+  0
+);
+ +

累加对象数组里的值

+ +

要累加对象数组中包含的值,必须提供初始值,以便各个item正确通过你的函数。

+ +
var initialValue = 0;
+var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
+    return accumulator + currentValue.x;
+},initialValue)
+
+console.log(sum) // logs 6
+ +

你也可以写成箭头函数的形式:

+ +
var initialValue = 0;
+var sum = [{x: 1}, {x:2}, {x:3}].reduce(
+    (accumulator, currentValue) => accumulator + currentValue.x
+    ,initialValue
+);
+
+console.log(sum) // logs 6
+
+ +

将二维数组转化为一维

+ +
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
+  function(a, b) {
+    return a.concat(b);
+  },
+  []
+);
+// flattened is [0, 1, 2, 3, 4, 5]
+
+ +

你也可以写成箭头函数的形式:

+ +
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
+ ( acc, cur ) => acc.concat(cur),
+ []
+);
+
+
+ +

计算数组中每个元素出现的次数

+ +
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
+
+var countedNames = names.reduce(function (allNames, name) {
+  if (name in allNames) {
+    allNames[name]++;
+  }
+  else {
+    allNames[name] = 1;
+  }
+  return allNames;
+}, {});
+// countedNames is:
+// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
+ +

按属性对object分类

+ +
var people = [
+  { name: 'Alice', age: 21 },
+  { name: 'Max', age: 20 },
+  { name: 'Jane', age: 20 }
+];
+
+function groupBy(objectArray, property) {
+  return objectArray.reduce(function (acc, obj) {
+    var key = obj[property];
+    if (!acc[key]) {
+      acc[key] = [];
+    }
+    acc[key].push(obj);
+    return acc;
+  }, {});
+}
+
+var groupedPeople = groupBy(people, 'age');
+// groupedPeople is:
+// {
+//   20: [
+//     { name: 'Max', age: 20 },
+//     { name: 'Jane', age: 20 }
+//   ],
+//   21: [{ name: 'Alice', age: 21 }]
+// }
+
+ +

使用扩展运算符和initialValue绑定包含在对象数组中的数组

+ +
// friends - 对象数组
+// where object field "books" - list of favorite books
+var friends = [{
+  name: 'Anna',
+  books: ['Bible', 'Harry Potter'],
+  age: 21
+}, {
+  name: 'Bob',
+  books: ['War and peace', 'Romeo and Juliet'],
+  age: 26
+}, {
+  name: 'Alice',
+  books: ['The Lord of the Rings', 'The Shining'],
+  age: 18
+}];
+
+// allbooks - list which will contain all friends' books +
+// additional list contained in initialValue
+var allbooks = friends.reduce(function(prev, curr) {
+  return [...prev, ...curr.books];
+}, ['Alphabet']);
+
+// allbooks = [
+//   'Alphabet', 'Bible', 'Harry Potter', 'War and peace',
+//   'Romeo and Juliet', 'The Lord of the Rings',
+//   'The Shining'
+// ]
+
+ +

数组去重

+ +
+

注意: 如果你正在使用一个可以兼容{{jsxref("Set")}} 和 {{jsxref("Array.from()")}} 的环境, 你可以使用let orderedArray = Array.from(new Set(myArray)); 来获得一个相同元素被移除的数组。

+
+ +
let myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd']
+let myOrderedArray = myArray.reduce(function (accumulator, currentValue) {
+  if (accumulator.indexOf(currentValue) === -1) {
+    accumulator.push(currentValue)
+  }
+  return accumulator
+}, [])
+
+console.log(myOrderedArray)
+ +
let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
+let result = arr.sort().reduce((init, current) => {
+    if(init.length === 0 || init[init.length-1] !== current) {
+        init.push(current);
+    }
+    return init;
+}, []);
+console.log(result); //[1,2,3,4,5]
+ +

按顺序运行Promise

+ +
/**
+ * Runs promises from array of functions that can return promises
+ * in chained manner
+ *
+ * @param {array} arr - promise arr
+ * @return {Object} promise object
+ */
+function runPromiseInSequence(arr, input) {
+  return arr.reduce(
+    (promiseChain, currentFunction) => promiseChain.then(currentFunction),
+    Promise.resolve(input)
+  );
+}
+
+// promise function 1
+function p1(a) {
+  return new Promise((resolve, reject) => {
+    resolve(a * 5);
+  });
+}
+
+// promise function 2
+function p2(a) {
+  return new Promise((resolve, reject) => {
+    resolve(a * 2);
+  });
+}
+
+// function 3  - will be wrapped in a resolved promise by .then()
+function f3(a) {
+ return a * 3;
+}
+
+// promise function 4
+function p4(a) {
+  return new Promise((resolve, reject) => {
+    resolve(a * 4);
+  });
+}
+
+const promiseArr = [p1, p2, f3, p4];
+runPromiseInSequence(promiseArr, 10)
+  .then(console.log);   // 1200
+
+ +

功能型函数管道

+ +
// Building-blocks to use for composition
+const double = x => x + x;
+const triple = x => 3 * x;
+const quadruple = x => 4 * x;
+
+// Function composition enabling pipe functionality
+const pipe = (...functions) => input => functions.reduce(
+    (acc, fn) => fn(acc),
+    input
+);
+
+// Composed functions for multiplication of specific values
+const multiply6 = pipe(double, triple);
+const multiply9 = pipe(triple, triple);
+const multiply16 = pipe(quadruple, quadruple);
+const multiply24 = pipe(double, triple, quadruple);
+
+// Usage
+multiply6(6); // 36
+multiply9(9); // 81
+multiply16(16); // 256
+multiply24(10); // 240
+
+ +

使用 reduce实现map

+ +
if (!Array.prototype.mapUsingReduce) {
+  Array.prototype.mapUsingReduce = function(callback, thisArg) {
+    return this.reduce(function(mappedArray, currentValue, index, array) {
+      mappedArray[index] = callback.call(thisArg, currentValue, index, array)
+      return mappedArray
+    }, [])
+  }
+}
+
+[1, 2, , 3].mapUsingReduce(
+  (currentValue, index, array) => currentValue + index + array.length
+) // [5, 7, , 10]
+
+ +

Polyfill

+ +
// Production steps of ECMA-262, Edition 5, 15.4.4.21
+// Reference: http://es5.github.io/#x15.4.4.21
+// https://tc39.github.io/ecma262/#sec-array.prototype.reduce
+if (!Array.prototype.reduce) {
+  Object.defineProperty(Array.prototype, 'reduce', {
+    value: function(callback /*, initialValue*/) {
+      if (this === null) {
+        throw new TypeError( 'Array.prototype.reduce ' +
+          'called on null or undefined' );
+      }
+      if (typeof callback !== 'function') {
+        throw new TypeError( callback +
+          ' is not a function');
+      }
+
+      // 1. Let O be ? ToObject(this value).
+      var o = Object(this);
+
+      // 2. Let len be ? ToLength(? Get(O, "length")).
+      var len = o.length >>> 0;
+
+      // Steps 3, 4, 5, 6, 7
+      var k = 0;
+      var value;
+
+      if (arguments.length >= 2) {
+        value = arguments[1];
+      } else {
+        while (k < len && !(k in o)) {
+          k++;
+        }
+
+        // 3. If len is 0 and initialValue is not present,
+        //    throw a TypeError exception.
+        if (k >= len) {
+          throw new TypeError( 'Reduce of empty array ' +
+            'with no initial value' );
+        }
+        value = o[k++];
+      }
+
+      // 8. Repeat, while k < len
+      while (k < len) {
+        // a. Let Pk be ! ToString(k).
+        // b. Let kPresent be ? HasProperty(O, Pk).
+        // c. If kPresent is true, then
+        //    i.  Let kValue be ? Get(O, Pk).
+        //    ii. Let accumulator be ? Call(
+        //          callbackfn, undefined,
+        //          « accumulator, kValue, k, O »).
+        if (k in o) {
+          value = callback(value, o[k], k, o);
+        }
+
+        // d. Increase k by 1.
+        k++;
+      }
+
+      // 9. Return accumulator.
+      return value;
+    }
+  });
+}
+
+ +

如果您需要兼容不支持Object.defineProperty的JavaScript引擎,那么最好不要 polyfill Array.prototype方法,因为你无法使其成为不可枚举的。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.4.4.21', 'Array.prototype.reduce')}}{{Spec2('ES5.1')}}初始定语. 实施于 JavaScript 1.8.
{{SpecName('ES6', '#sec-array.prototype.reduce', 'Array.prototype.reduce')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.reduce', 'Array.prototype.reduce')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.reduce")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/reduceright/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/reduceright/index.html new file mode 100644 index 0000000000..e4846dbfbf --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/reduceright/index.html @@ -0,0 +1,409 @@ +--- +title: Array.prototype.reduceRight() +slug: Web/JavaScript/Reference/Global_Objects/Array/ReduceRight +tags: + - JavaScript + - 原型 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/ReduceRight +--- +
{{JSRef}}
+ +

reduceRight() 方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。

+ +
{{EmbedInteractiveExample("pages/js/array-reduce-right.html")}}
+ + + +

对于从左至右遍历的相似方法请参阅 {{jsxref("Array.prototype.reduce()")}}.

+ +

语法

+ +
arr.reduceRight(callback(accumulator, currentValue[, index[, array]])[, initialValue])
+ +

参数

+ +
+
callback
+
一个回调函数,用于操作数组中的每个元素,它可接受四个参数: +
+
accumulator
+
累加器:上一次调用回调函数时,回调函数返回的值。首次调用回调函数时,如果 initialValue 存在,累加器即为 initialValue,否则须为数组中的最后一个元素(详见下方 initialValue 处相关说明)。
+
currentValue
+
当前元素:当前被处理的元素。
+
index{{optional_inline}}
+
数组中当前被处理的元素的索引。
+
array{{optional_inline}}
+
调用 reduceRight() 的数组。
+
+
+
initialValue{{optional_inline}} 
+
首次调用 callback 函数时,累加器 accumulator 的值。如果未提供该初始值,则将使用数组中的最后一个元素,并跳过该元素。如果不给出初始值,则需保证数组不为空。
+ 否则,在空数组上调用 reducereduceRight 且未提供初始值(例如 [].reduce( (acc, cur, idx, arr) => {} ) )的话,会导致类型错误 TypeError: reduce of empty array with no initial value
+
+

返回值

+
+
+

执行之后的返回值。

+
+
+ +

描述

+ +

reduceRight 为数组中每个元素调用一次 callback 回调函数,但是数组中被删除的索引或从未被赋值的索引会跳过。回调函数接受四个参数:初始值(或上次调用回调的返回值)、当前元素值、当前索引,以及调用迭代的当前数组。

+ +

可以像下面这样调用 reduceRight 的回调函数 callback

+ +
array.reduceRight(function(accumulator, currentValue, index, array) {
+  // ...
+});
+ +

首次调用回调函数时,accumulatorcurrentValue 的可能取值情况有两种:

+ + + +

如果数组为空,但提供了 initialValue 参数,或如果数组中只有一个元素,且没有提供 initialValue 参数,将会直接返回 initialValue 参数或数组中的那一个元素。这两种情况下,都不会调用 callback 函数。

+ +

如果数组为空,且没有提供 initialValue 参数,则会抛出一个 TypeError 错误。

+ +

最终,首次调用时的情况可汇总为此表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
数组内元素数量是否提供 initialValue结果
> 1未提供accumulator数组中(下略)最后一个元素
+ currentValue 为倒数第二个元素
提供accumulator 为 initialValue
+ currentValue 为最后一个元素
= 1未提供直接返回数组中的唯一一个元素
= 0提供直接返回 initialValue
未提供抛出 TypeError 错误
+ +

该函数的完整执行过程见下例:

+ +
[0, 1, 2, 3, 4].reduceRight(function(previousValue, currentValue, index, array) {
+    return previousValue + currentValue;
+});
+
+ +

一共会调用四次回调函数,每次调用的参数及返回值如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
callbackpreviousValuecurrentValueindexarray返回值
第一次调用433[0,1,2,3,4]7
第二次调用722[0,1,2,3,4]9
第三次调用911[0,1,2,3,4]10
第四次调用1000[0,1,2,3,4]10
+ +

reduceRight 返回值是最后一次调用回调的返回值(10)。

+ +

如果提供了一个 initialValue 参数,则结果如下:

+ +
[0, 1, 2, 3, 4].reduceRight(function(previousValue, currentValue, index, array) {
+    return previousValue + currentValue;
+}, 10);
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
callbackpreviousValuecurrentValueindexarray返回值
第一次调用1044[0,1,2,3,4]14
第二次调用1433[0,1,2,3,4]17
第三次调用1722[0,1,2,3,4]19
第四次调用1911[0,1,2,3,4]20
第五次调用2000[0,1,2,3,4]20
+ +

这时,reduceRight 返回值为 20。

+ +

示例

+ +

求一个数组中所有值的和

+ +
var sum = [0, 1, 2, 3].reduceRight(function(a, b) {
+  return a + b;
+});
+// sum is 6
+ +

扁平化(flatten)一个二维数组

+ +
var flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
+    return a.concat(b);
+}, []);
+// flattened is [4, 5, 2, 3, 0, 1]
+
+ +

运行一个带有回调每个函数将其结果传给下一个的异步函数列表

+ +
const waterfall = (...functions) => (callback, ...args) =>
+  functions.reduceRight(
+    (composition, fn) => (...results) => fn(composition, ...results),
+    callback
+  )(...args);
+
+const randInt = max => Math.floor(Math.random() * max)
+
+const add5 = (callback, x) => {
+  setTimeout(callback, randInt(1000), x + 5);
+};
+const mult3 = (callback, x) => {
+  setTimeout(callback, randInt(1000), x * 3);
+};
+const sub2 = (callback, x) => {
+  setTimeout(callback, randInt(1000), x - 2);
+};
+const split = (callback, x) => {
+  setTimeout(callback, randInt(1000), x, x);
+};
+const add = (callback, x, y) => {
+  setTimeout(callback, randInt(1000), x + y);
+};
+const div4 = (callback, x) => {
+  setTimeout(callback, randInt(1000), x / 4);
+};
+
+const computation = waterfall(add5, mult3, sub2, split, add, div4);
+computation(console.log, 5) // -> 14
+
+// same as:
+
+const computation2 = (input, callback) => {
+  const f6 = x=> div4(callback, x);
+  const f5 = (x, y) => add(f6, x, y);
+  const f4 = x => split(f5, x);
+  const f3 = x => sub2(f4, x);
+  const f2 = x => mult3(f3, x);
+  add5(f2, input);
+}
+ +

展示 reducereduceRight 之间的区别

+ +
var a = ['1', '2', '3', '4', '5'];
+var left  = a.reduce(function(prev, cur)      { return prev + cur; });
+var right = a.reduceRight(function(prev, cur) { return prev + cur; });
+
+console.log(left);  // "12345"
+console.log(right); // "54321"
+ +

定义可组合函数

+ +

组合函数的概念简单,它只是简单地结合了多个函数。它是一个从右向左流动的函数,用上一个函数的输出调用每个函数。

+ +
/**
+ * Function Composition is way in which result of one function can
+ * be passed to another and so on.
+ *
+ * h(x) = f(g(x))
+ *
+ * Function execution happens right to left
+ *
+ * https://en.wikipedia.org/wiki/Function_composition
+ */
+
+const compose = (...args) => (value) => args.reduceRight((acc, fn) => fn(acc), value)
+
+// Increament passed number
+const inc = (n) => n + 1
+
+// Doubles the passed value
+const double = (n) => n * 2
+
+// using composition function
+console.log(compose(double, inc)(2)); // 6
+
+// using composition function
+console.log(compose(inc, double)(2)); // 5
+ +

兼容旧环境(Polyfill)

+ +

reduceRight 被添加到 ECMA-262 标准第 5 版,因此它在某些实现环境中可能不被支持。把下面的代码添加到脚本开头可以解决此问题,从而允许在那些没有原生支持 reduceRight 的实现环境中使用它。

+ +
// Production steps of ECMA-262, Edition 5, 15.4.4.22
+// Reference: http://es5.github.io/#x15.4.4.22
+if ('function' !== typeof Array.prototype.reduceRight) {
+  Array.prototype.reduceRight = function(callback /*, initialValue*/) {
+    'use strict';
+    if (null === this || 'undefined' === typeof this) {
+      throw new TypeError('Array.prototype.reduceRight called on null or undefined');
+    }
+    if ('function' !== typeof callback) {
+      throw new TypeError(callback + ' is not a function');
+    }
+    var t = Object(this), len = t.length >>> 0, k = len - 1, value;
+    if (arguments.length >= 2) {
+      value = arguments[1];
+    } else {
+      while (k >= 0 && !(k in t)) {
+        k--;
+      }
+      if (k < 0) {
+        throw new TypeError('reduceRight of empty array with no initial value');
+      }
+      value = t[k--];
+    }
+    for (; k >= 0; k--) {
+      if (k in t) {
+        value = callback(value, t[k], k, t);
+      }
+    }
+    return value;
+  };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.4.4.22', 'Array.prototype.reduceRight')}}{{Spec2('ES5.1')}}Initial definition.
+ Implemented in JavaScript 1.8
{{SpecName('ES6', '#sec-array.prototype.reduceright', 'Array.prototype.reduceRight')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.reduceright', 'Array.prototype.reduceRight')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.reduceRight")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/reverse/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/reverse/index.html new file mode 100644 index 0000000000..a9c984245f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/reverse/index.html @@ -0,0 +1,141 @@ +--- +title: Array.prototype.reverse() +slug: Web/JavaScript/Reference/Global_Objects/Array/reverse +tags: + - Array + - Array.prototype.reverse() + - JavaScript + - 原型 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/reverse +--- +
{{JSRef}}
+ +

reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。

+ +
{{EmbedInteractiveExample("pages/js/array-reverse.html")}}
+ +
+ +
+ +

语法

+ +
 arr.reverse()
+ +

返回值

+ +

颠倒后的数组。

+ +

描述

+ +

reverse 方法颠倒数组中元素的位置,改变了数组,并返回该数组的引用。

+ +

reverse方法是特意类化的;此方法可被 called 或 applied于类似数组对象。对象如果不包含反映一系列连续的、基于零的数值属性中的最后一个长度的属性,则该对象可能不会以任何有意义的方式运行。

+ +

示例

+ +

颠倒数组中的元素

+ +

下例将会创建一个数组 sourceArray,其包含三个元素,然后颠倒该数组。

+ +

 reverse() 的调用返回了一个颠倒后的数组 a的引用。

+ +
const a = [1, 2, 3];
+
+console.log(a); // [1, 2, 3]
+
+a.reverse();
+
+console.log(a); // [3, 2, 1]
+ +

颠倒类数组中的元素

+ +

下例创造了一个类数组对象 a, 包含3个元素和一个 length 属性, 然后颠倒这个类数组对象。  reverse() 的调用返回一个颠倒后的类数组对象 a的引用。

+ +
const a = {0: 1, 1: 2, 2: 3, length: 3};
+
+console.log(a); // {0: 1, 1: 2, 2: 3, length: 3}
+
+Array.prototype.reverse.call(a); //same syntax for using apply()
+
+console.log(a); // {0: 3, 1: 2, 2: 1, length: 3}
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.4.4.8', 'Array.prototype.reverse')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype.reverse', 'Array.prototype.reverse')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.reverse', 'Array.prototype.reverse')}}{{Spec2('ESDraft')}} 
+  
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-15.4.4.8', 'Array.prototype.reverse')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype.reverse', 'Array.prototype.reverse')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.reverse")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/shift/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/shift/index.html new file mode 100644 index 0000000000..3675c12bc4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/shift/index.html @@ -0,0 +1,129 @@ +--- +title: Array.prototype.shift() +slug: Web/JavaScript/Reference/Global_Objects/Array/shift +tags: + - Array.prototype.shift() + - JavaScript + - 原型 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/shift +--- +
{{JSRef}}
+ +

shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

+ +
{{EmbedInteractiveExample("pages/js/array-shift.html")}}
+ + + +

语法

+ +
arr.shift()
+ + + +

返回值 

+ +

从数组中删除的元素; 如果数组为空则返回{{jsxref("undefined")}} 。 

+ +

描述

+ +

shift 方法移除索引为 0 的元素(即第一个元素),并返回被移除的元素,其他元素的索引值随之减 1。如果 {{jsxref("Array.length", "length")}} 属性的值为 0 (长度为 0),则返回 {{jsxref("undefined")}}。

+ +

shift 方法并不局限于数组:这个方法能够通过 {{jsxref("Function.call", "call")}} 或 {{jsxref("Function.apply", "apply")}} 方法作用于类似数组的对象上。但是对于没有 length 属性(从0开始的一系列连续的数字属性的最后一个)的对象,调用该方法可能没有任何意义。

+ +

{{jsxref("Array.prototype.pop()")}} 有着和 shift相似的行为, 但是是作用在数组的最后一个元素上的。

+ +

示例

+ +

移除数组中的一个元素

+ +

以下代码显示了删除其第一个元素之前和之后的myFish数组。它还显示已删除的元素:

+ +
let myFish = ['angel', 'clown', 'mandarin', 'surgeon'];
+
+console.log('调用 shift 之前: ' + myFish);
+// "调用 shift 之前: angel,clown,mandarin,surgeon"
+
+var shifted = myFish.shift();
+
+console.log('调用 shift 之后: ' + myFish);
+// "调用 shift 之后: clown,mandarin,surgeon"
+
+console.log('被删除的元素: ' + shifted);
+// "被删除的元素: angel"
+ +
var myFish = ['angel', 'clown', 'mandarin', 'surgeon'];
+
+console.log('myFish before:', JSON.stringify(myFish));
+// myFish before: ['angel', 'clown', 'mandarin', 'surgeon']
+
+var shifted = myFish.shift();
+
+console.log('myFish after:', myFish);
+// myFish after: ['clown', 'mandarin', 'surgeon']
+
+console.log('Removed this element:', shifted);
+// Removed this element: angel
+ +

在while循环中使用shift()

+ +

shift() 方法经常用于while loop的环境中.。下例中每个循环将要从一个数组中移除下一项元素,直至它成为空数组。

+ +
var names = ["Andrew", "Edward", "Paul", "Chris" ,"John"];
+
+while( (i = names.shift()) !== undefined ) {
+    console.log(i);
+}
+// Andrew, Edward, Paul, Chris, John
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.4.4.9', 'Array.prototype.shift')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype.shift', 'Array.prototype.shift')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.shift', 'Array.prototype.shift')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ +
+
+ + +

{{Compat("javascript.builtins.Array.shift")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/slice/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/slice/index.html new file mode 100644 index 0000000000..eb68df4907 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/slice/index.html @@ -0,0 +1,253 @@ +--- +title: Array.prototype.slice() +slug: Web/JavaScript/Reference/Global_Objects/Array/slice +tags: + - Array + - JavaScript + - Prototype + - 原型 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/slice +--- +
{{JSRef}}
+ +

slice() 方法返回一个新的数组对象,这一对象是一个由 beginend 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。

+ +
{{EmbedInteractiveExample("pages/js/array-slice.html")}}
+ + + +

语法

+ +
arr.slice([begin[, end]])
+ +

参数

+ +
+
begin {{optional_inline}}
+
提取起始处的索引(从 0 开始),从该索引开始提取原数组元素。
+
如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2) 表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。
+
如果省略 begin,则 slice 从索引 0 开始。
+
如果 begin 超出原数组的索引范围,则会返回空数组。
+
+ +
+
end {{optional_inline}}
+
提取终止处的索引(从 0 开始),在该索引处结束提取原数组元素。slice 会提取原数组中索引从 begin 到 end 的所有元素(包含 begin,但不包含 end)。
+
slice(1,4) 会提取原数组中从第二个元素开始一直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。
+
如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1) 表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。
+
如果 end 被省略,则 slice 会一直提取到原数组末尾。
+
如果 end 大于数组的长度,slice 也会一直提取到原数组末尾。
+
+ +

返回值

+ +

一个含有被提取元素的新数组。

+ +

描述

+ +

slice 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:

+ + + + + +

如果向两个数组任一中添加了新元素,则另一个不会受到影响。

+ +

示例

+ +

返回现有数组的一部分

+ +
var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
+var citrus = fruits.slice(1, 3);
+
+// fruits contains ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
+// citrus contains ['Orange','Lemon']
+
+ +
+

译者注:citrus [n.] 柑橘类果实

+
+ +

使用 slice

+ +

在下例中, slicemyCar 中创建了一个新数组newCar。两个数组都包含了一个 myHonda 对象的引用。当 myHondacolor 属性改变为 purple,则两个数组中的对应元素都会随之改变。

+ +
// 使用 slice 方法从 myCar 中创建一个 newCar。
+var myHonda = { color: 'red', wheels: 4, engine: { cylinders: 4, size: 2.2 } };
+var myCar = [myHonda, 2, "cherry condition", "purchased 1997"];
+var newCar = myCar.slice(0, 2);
+
+// 输出 myCar、newCar 以及各自的 myHonda 对象引用的 color 属性。
+console.log(' myCar = ' + JSON.stringify(myCar));
+console.log('newCar = ' + JSON.stringify(newCar));
+console.log(' myCar[0].color = ' + JSON.stringify(myCar[0].color));
+console.log('newCar[0].color = ' + JSON.stringify(newCar[0].color));
+
+// 改变 myHonda 对象的 color 属性.
+myHonda.color = 'purple';
+console.log('The new color of my Honda is ' + myHonda.color);
+
+//输出 myCar、newCar 中各自的 myHonda 对象引用的 color 属性。
+console.log(' myCar[0].color = ' + myCar[0].color);
+console.log('newCar[0].color = ' + newCar[0].color);
+
+ +

上述代码输出:

+ +
 myCar = [{color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}}, 2,
+       'cherry condition', 'purchased 1997']
+newCar = [{color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}}, 2]
+ myCar[0].color = red
+newCar[0].color = red
+The new color of my Honda is purple
+ myCar[0].color = purple
+newCar[0].color = purple
+
+ +

类数组(Array-like)对象

+ +

slice 方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。你只需将该方法绑定到这个对象上。 一个函数中的  {{jsxref("Functions/arguments", "arguments")}} 就是一个类数组对象的例子。

+ +
function list() {
+  return Array.prototype.slice.call(arguments);
+}
+
+var list1 = list(1, 2, 3); // [1, 2, 3]
+
+ +

除了使用 Array.prototype.slice.call(arguments),你也可以简单的使用 [].slice.call(arguments) 来代替。另外,你可以使用 bind 来简化该过程。

+ +
var unboundSlice = Array.prototype.slice;
+var slice = Function.prototype.call.bind(unboundSlice);
+
+function list() {
+  return slice(arguments);
+}
+
+var list1 = list(1, 2, 3); // [1, 2, 3]
+
+ +

精简跨浏览器行为

+ +

根据规范,使用 Array.prototype.slice 转换宿主对象(如 DOM 对象)时,不必遵循 Mozilla 的默认行为,即可以转化任何符合条件的伪数组宿主对象为数组,IE < 9 没有遵循,而 IE9 + 遵循这个行为,但是稍加改造可以使其在跨浏览器使用时更可靠。只要其他现代浏览器继续支持该行为,目前 IE 9+、FireFox、Chrome、Safari 以及 Opera 都支持,开发者在使用下面代码时遍历 DOM 时就不会被该方法的字面意义误导,即 IE < 9 不能转化 DOM Collections。开发者可以安全地根据语义知道该方法的实际上的标准行为。(下面的代码还修正了 IE 中 slice() 方法第二个参数不允许为显式的 {{jsxref("Global_Objects/null", "null")}}/{{jsxref("Global_Objects/undefined", "undefined")}} 值的问题,其他现代浏览器,包括 IE9+ 都允许)。

+ +
/**
+ * Shim for "fixing" IE's lack of support (IE < 9) for applying slice
+ * on host objects like NamedNodeMap, NodeList, and HTMLCollection
+ * (technically, since host objects have been implementation-dependent,
+ * at least before ES2015, IE hasn't needed to work this way).
+ * Also works on strings, fixes IE < 9 to allow an explicit undefined
+ * for the 2nd argument (as in Firefox), and prevents errors when
+ * called on other DOM objects.
+ */
+(function () {
+  'use strict';
+  var _slice = Array.prototype.slice;
+
+  try {
+    // Can't be used with DOM elements in IE < 9
+    _slice.call(document.documentElement);
+  } catch (e) { // Fails in IE < 9
+    // This will work for genuine arrays, array-like objects,
+    // NamedNodeMap (attributes, entities, notations),
+    // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes),
+    // and will not fail on other DOM objects (as do DOM elements in IE < 9)
+    Array.prototype.slice = function(begin, end) {
+      // IE < 9 gets unhappy with an undefined end argument
+      end = (typeof end !== 'undefined') ? end : this.length;
+
+      // For native Array objects, we use the native slice function
+      if (Object.prototype.toString.call(this) === '[object Array]'){
+        return _slice.call(this, begin, end);
+      }
+
+      // For array like object we handle it ourselves.
+      var i, cloned = [],
+        size, len = this.length;
+
+      // Handle negative value for "begin"
+      var start = begin || 0;
+      start = (start >= 0) ? start : Math.max(0, len + start);
+
+      // Handle negative value for "end"
+      var upTo = (typeof end == 'number') ? Math.min(end, len) : len;
+      if (end < 0) {
+        upTo = len + end;
+      }
+
+      // Actual expected size of the slice
+      size = upTo - start;
+
+      if (size > 0) {
+        cloned = new Array(size);
+        if (this.charAt) {
+          for (i = 0; i < size; i++) {
+            cloned[i] = this.charAt(start + i);
+          }
+        } else {
+          for (i = 0; i < size; i++) {
+            cloned[i] = this[start + i];
+          }
+        }
+      }
+
+      return cloned;
+    };
+  }
+}());
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
+ Implemented in JavaScript 1.2
{{SpecName('ES5.1', '#sec-15.4.4.10', 'Array.prototype.slice')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype.slice', 'Array.prototype.slice')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.slice', 'Array.prototype.slice')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.slice")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/some/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/some/index.html new file mode 100644 index 0000000000..734cace600 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/some/index.html @@ -0,0 +1,215 @@ +--- +title: Array.prototype.some() +slug: Web/JavaScript/Reference/Global_Objects/Array/some +tags: + - Array + - ECMAScript5 + - JavaScript + - Method + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Array/some +--- +
{{JSRef}}
+ +

some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。

+ +
+

注意:如果用一个空数组进行测试,在任何情况下它返回的都是false

+
+ +
{{EmbedInteractiveExample("pages/js/array-some.html")}}
+ +

语法

+ +
arr.some(callback(element[, index[, array]])[, thisArg])
+ +

参数

+ +
+
callback
+
用来测试每个元素的函数,接受三个参数: +
+
element
+
数组中正在处理的元素。
+
index {{Optional_inline}}
+
数组中正在处理的元素的索引值。
+
array{{Optional_inline}}
+
some()被调用的数组。
+
+
+
thisArg{{Optional_inline}}
+
执行 callback 时使用的 this 值。
+
+ +

返回值

+ +

数组中有至少一个元素通过回调函数的测试就会返回true;所有元素都没有通过回调函数的测试返回值才会为false。

+ +

描述

+ +

some() 为数组中的每一个元素执行一次 callback 函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some() 将会立即返回 true。否则,some() 返回 falsecallback 只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。

+ +

callback 被调用时传入三个参数:元素的值,元素的索引,被遍历的数组。

+ +

如果一个thisArg参数提供给some(),它将被用作调用的 callback的 this 值。否则, 它的 this value将是 undefinedthis的值最终通过callback来观察,根据 the usual rules for determining the this seen by a function的this判定规则来确定。

+ +

some() 被调用时不会改变数组。

+ +

some() 遍历的元素的范围在第一次调用 callback. 前就已经确定了。在调用 some() 后被添加到数组中的值不会被 callback 访问到。如果数组中存在且还未被访问到的元素被 callback 改变了,则其传递给 callback 的值是 some() 访问到它那一刻的值。已经被删除的元素不会被访问到。

+ +

示例

+ +

测试数组元素的值

+ +

下面的例子检测在数组中是否有元素大于 10。

+ +
function isBiggerThan10(element, index, array) {
+  return element > 10;
+}
+
+[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
+[12, 5, 8, 1, 4].some(isBiggerThan10); // true
+ +

使用箭头函数测试数组元素的值

+ +

箭头函数 可以通过更简洁的语法实现相同的用例.

+ +
[2, 5, 8, 1, 4].some(x => x > 10);  // false
+[12, 5, 8, 1, 4].some(x => x > 10); // true
+ +

{{ EmbedLiveSample('Testing_array_elements_using_arrow_functions', '', '', '', 'Web/JavaScript/Reference/Global_Objects/Array/some') }}

+ +

判断数组元素中是否存在某个值

+ +

此例中为模仿 includes()  方法, 若元素在数组中存在, 则回调函数返回值为 true :

+ +
var fruits = ['apple', 'banana', 'mango', 'guava'];
+
+function checkAvailability(arr, val) {
+  return arr.some(function(arrVal) {
+    return val === arrVal;
+  });
+}
+
+checkAvailability(fruits, 'kela');   // false
+checkAvailability(fruits, 'banana'); // true
+ +

{{ EmbedLiveSample('Checking_whether_a_value_exists_in_an_array', '', '', '', 'Web/JavaScript/Reference/Global_Objects/Array/some') }}

+ +

使用箭头函数判断数组元素中是否存在某个值

+ +
var fruits = ['apple', 'banana', 'mango', 'guava'];
+
+function checkAvailability(arr, val) {
+  return arr.some(arrVal => val === arrVal);
+}
+
+checkAvailability(fruits, 'kela');   // false
+checkAvailability(fruits, 'banana'); // true
+ +

{{ EmbedLiveSample('Checking_whether_a_value_exists_using_an_arrow_function', '', '', '', 'Experiment:StaticExamplesOnTop/JavaScript/Array/some') }}

+ + + +

将任意值转换为布尔类型

+ +
var TRUTHY_VALUES = [true, 'true', 1];
+
+function getBoolean(value) {
+  'use strict';
+
+  if (typeof value === 'string') {
+    value = value.toLowerCase().trim();
+  }
+
+  return TRUTHY_VALUES.some(function(t) {
+    return t === value;
+  });
+}
+
+getBoolean(false);   // false
+getBoolean('false'); // false
+getBoolean(1);       // true
+getBoolean('true');  // true
+
+ +

{{ EmbedLiveSample('Converting_any_value_to_Boolean', '', '', '', 'Web/JavaScript/Reference/Global_Objects/Array/some') }}

+ +

Polyfill

+ +

在第 5 版时,some() 被添加进 ECMA-262 标准;这样导致某些实现环境可能不支持它。你可以把下面的代码插入到脚本的开头来解决此问题,从而允许在那些没有原生支持它的实现环境中使用它。该算法是 ECMA-262 第 5 版中指定的算法,假定 Object 和 TypeError 拥有他们的初始值,且 fun.call 等价于 {{jsxref("Function.prototype.call")}}

+ +
// Production steps of ECMA-262, Edition 5, 15.4.4.17
+// Reference: http://es5.github.io/#x15.4.4.17
+if (!Array.prototype.some) {
+  Array.prototype.some = function(fun/*, thisArg*/) {
+    'use strict';
+
+    if (this == null) {
+      throw new TypeError('Array.prototype.some called on null or undefined');
+    }
+
+    if (typeof fun !== 'function') {
+      throw new TypeError();
+    }
+
+    var t = Object(this);
+    var len = t.length >>> 0;
+
+    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
+    for (var i = 0; i < len; i++) {
+      if (i in t && fun.call(thisArg, t[i], i, t)) {
+        return true;
+      }
+    }
+
+    return false;
+  };
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.4.4.17', 'Array.prototype.some')}}{{Spec2('ES5.1')}} +

Initial definition. Implemented in JavaScript 1.6.

+
{{SpecName('ES6', '#sec-array.prototype.some', 'Array.prototype.some')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.some', 'Array.prototype.some')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.builtins.Array.some")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/sort/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/sort/index.html new file mode 100644 index 0000000000..e9f9808420 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/sort/index.html @@ -0,0 +1,265 @@ +--- +title: Array.prototype.sort() +slug: Web/JavaScript/Reference/Global_Objects/Array/sort +tags: + - Array + - Array & sort + - JavaScript + - Prototype + - sort +translation_of: Web/JavaScript/Reference/Global_Objects/Array/sort +--- +
{{JSRef}}
+ +

sort() 方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的

+ +

由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。

+ +
{{EmbedInteractiveExample("pages/js/array-sort.html")}}
+ + + +

语法

+ +
arr.sort([compareFunction])
+
+ +

参数

+ +
+
compareFunction {{optional_inline}}
+
用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。 +
+
firstEl
+
第一个用于比较的元素。
+
secondEl
+
第二个用于比较的元素。
+
+
+
+ +

返回值

+ +

排序后的数组。请注意,数组已原地排序,并且不进行复制。

+ +

描述

+ +

如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序。例如 "Banana" 会被排列到 "cherry" 之前。当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFunction),比较的数字会先被转换为字符串,所以在Unicode顺序上 "80" 要比 "9" 要靠前。

+ +

如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:

+ + + + + + + +

所以,比较函数格式如下:

+ +
function compare(a, b) {
+  if (a < b ) {           // 按某种排序标准进行比较, a 小于 b
+    return -1;
+  }
+  if (a > b ) {
+    return 1;
+  }
+  // a must be equal to b
+  return 0;
+}
+
+ +

要比较数字而非字符串,比较函数可以简单的以 a 减 b,如下的函数将会将数组升序排列

+ +
function compareNumbers(a, b) {
+  return a - b;
+}
+
+ +

sort 方法可以使用 {{jsxref("Operators/function", "函数表达式", "", 1)}} 方便地书写:

+ +
var numbers = [4, 2, 5, 1, 3];
+numbers.sort(function(a, b) {
+  return a - b;
+});
+console.log(numbers);
+
+也可以写成:
+var numbers = [4, 2, 5, 1, 3];
+numbers.sort((a, b) => a - b);
+console.log(numbers);
+
+// [1, 2, 3, 4, 5]
+
+ +

对象可以按照某个属性排序:

+ +
var items = [
+  { name: 'Edward', value: 21 },
+  { name: 'Sharpe', value: 37 },
+  { name: 'And', value: 45 },
+  { name: 'The', value: -12 },
+  { name: 'Magnetic' },
+  { name: 'Zeros', value: 37 }
+];
+
+// sort by value
+items.sort(function (a, b) {
+  return (a.value - b.value)
+});
+
+// sort by name
+items.sort(function(a, b) {
+  var nameA = a.name.toUpperCase(); // ignore upper and lowercase
+  var nameB = b.name.toUpperCase(); // ignore upper and lowercase
+  if (nameA < nameB) {
+    return -1;
+  }
+  if (nameA > nameB) {
+    return 1;
+  }
+
+  // names must be equal
+  return 0;
+});
+ +

示例

+ +

创建、显示及排序数组

+ +

下述示例创建了四个数组,并展示原数组。之后对数组进行排序。对比了数字数组分别指定与不指定比较函数的结果。

+ +
var stringArray = ["Blue", "Humpback", "Beluga"];
+var numericStringArray = ["80", "9", "700"];
+var numberArray = [40, 1, 5, 200];
+var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];
+
+function compareNumbers(a, b)
+{
+  return a - b;
+}
+
+console.log('stringArray:' + stringArray.join());
+console.log('Sorted:' + stringArray.sort());
+
+console.log('numberArray:' + numberArray.join());
+console.log('Sorted without a compare function:'+ numberArray.sort());
+console.log('Sorted with compareNumbers:'+ numberArray.sort(compareNumbers));
+
+console.log('numericStringArray:'+ numericStringArray.join());
+console.log('Sorted without a compare function:'+ numericStringArray.sort());
+console.log('Sorted with compareNumbers:'+ numericStringArray.sort(compareNumbers));
+
+console.log('mixedNumericArray:'+ mixedNumericArray.join());
+console.log('Sorted without a compare function:'+ mixedNumericArray.sort());
+console.log('Sorted with compareNumbers:'+ mixedNumericArray.sort(compareNumbers));
+
+ +

该示例的返回结果如下。输出显示,当使用比较函数后,数字数组会按照数字大小排序。

+ +
stringArray: Blue,Humpback,Beluga
+Sorted: Beluga,Blue,Humpback
+
+numberArray: 40,1,5,200
+Sorted without a compare function: 1,200,40,5
+Sorted with compareNumbers: 1,5,40,200
+
+numericStringArray: 80,9,700
+Sorted without a compare function: 700,80,9
+Sorted with compareNumbers: 9,80,700
+
+mixedNumericArray: 80,9,700,40,1,5,200
+Sorted without a compare function: 1,200,40,5,700,80,9
+Sorted with compareNumbers: 1,5,9,40,80,200,700
+
+ +

对非 ASCII 字符排序

+ +

当排序非 ASCII 字符的字符串(如包含类似 e, é, è, a, ä 等字符的字符串)。一些非英语语言的字符串需要使用 {{jsxref("String.localeCompare")}}。这个函数可以将函数排序到正确的顺序。

+ +
var items = ['réservé', 'premier', 'cliché', 'communiqué', 'café', 'adieu'];
+items.sort(function (a, b) {
+  return a.localeCompare(b);
+});
+
+// items is ['adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé']
+
+ +

使用映射改善排序

+ +

compareFunction 可能需要对元素做多次映射以实现排序,尤其当 compareFunction 较为复杂,且元素较多的时候,某些 compareFunction 可能会导致很高的负载。使用 map 辅助排序将会是一个好主意。基本思想是首先将数组中的每个元素比较的实际值取出来,排序后再将数组恢复。

+ +
// 需要被排序的数组
+var list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];
+
+// 对需要排序的数字和位置的临时存储
+var mapped = list.map(function(el, i) {
+  return { index: i, value: el.toLowerCase() };
+})
+
+// 按照多个值排序数组
+mapped.sort(function(a, b) {
+  return +(a.value > b.value) || +(a.value === b.value) - 1;
+});
+
+// 根据索引得到排序的结果
+var result = mapped.map(function(el){
+  return list[el.index];
+});
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.4.4.11', 'Array.prototype.sort')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype.sort', 'Array.prototype.sort')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.sort', 'Array.prototype.sort')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.sort")}}

+
+
+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/splice/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/splice/index.html new file mode 100644 index 0000000000..2dcb909975 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/splice/index.html @@ -0,0 +1,165 @@ +--- +title: Array.prototype.splice() +slug: Web/JavaScript/Reference/Global_Objects/Array/splice +tags: + - Array + - JavaScript + - 原型 + - 参考 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/splice +--- +
{{JSRef}}
+ +

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

+ +
{{EmbedInteractiveExample("pages/js/array-splice.html")}}
+ + + +

语法

+ +
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
+
+ +

参数

+ +
+
start​
+
指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于array.length-n);如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
+
deleteCount {{optional_inline}}
+
整数,表示要移除的数组元素的个数。
+
如果 deleteCount 大于 start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。
+
如果 deleteCount 被省略了,或者它的值大于等于array.length - start(也就是说,如果它大于或者等于start之后的所有元素的数量),那么start之后数组的所有元素都会被删除。
+
如果 deleteCount 是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。
+
item1, item2, ... {{optional_inline}}
+
要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。
+
+ +

返回值

+ +

由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。

+ +

描述

+ +

如果添加进数组的元素个数不等于被删除的元素个数,数组的长度会发生相应的改变。

+ +

示例

+ +

从第 2 位开始删除 0 个元素,插入“drum”

+ +
var myFish = ["angel", "clown", "mandarin", "sturgeon"];
+var removed = myFish.splice(2, 0, "drum");
+
+// 运算后的 myFish: ["angel", "clown", "drum", "mandarin", "sturgeon"]
+// 被删除的元素: [], 没有元素被删除
+
+ +

从第 2 位开始删除 0 个元素,插入“drum” 和 "guitar"

+ +
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
+var removed = myFish.splice(2, 0, 'drum', 'guitar');
+
+// 运算后的 myFish: ["angel", "clown", "drum", "guitar", "mandarin", "sturgeon"]
+// 被删除的元素: [], 没有元素被删除
+
+ +

从第 3 位开始删除 1 个元素

+ +
var myFish = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
+var removed = myFish.splice(3, 1);
+
+// 运算后的 myFish: ["angel", "clown", "drum", "sturgeon"]
+// 被删除的元素: ["mandarin"]
+
+ +

从第 2 位开始删除 1 个元素,插入“trumpet”

+ +
var myFish = ['angel', 'clown', 'drum', 'sturgeon'];
+var removed = myFish.splice(2, 1, "trumpet");
+
+// 运算后的 myFish: ["angel", "clown", "trumpet", "sturgeon"]
+// 被删除的元素: ["drum"]
+
+ +

从第 0 位开始删除 2 个元素,插入"parrot"、"anemone"和"blue"

+ +
var myFish = ['angel', 'clown', 'trumpet', 'sturgeon'];
+var removed = myFish.splice(0, 2, 'parrot', 'anemone', 'blue');
+
+// 运算后的 myFish: ["parrot", "anemone", "blue", "trumpet", "sturgeon"]
+// 被删除的元素: ["angel", "clown"]
+
+ +

从第 2 位开始删除 2 个元素

+ +
var myFish = ['parrot', 'anemone', 'blue', 'trumpet', 'sturgeon'];
+var removed = myFish.splice(myFish.length - 3, 2);
+
+// 运算后的 myFish: ["parrot", "anemone", "sturgeon"]
+// 被删除的元素: ["blue", "trumpet"]
+
+ +

从倒数第 2 位开始删除 1 个元素

+ +
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
+var removed = myFish.splice(-2, 1);
+
+// 运算后的 myFish: ["angel", "clown", "sturgeon"]
+// 被删除的元素: ["mandarin"]
+ +

从第 2 位开始删除所有元素

+ +
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
+var removed = myFish.splice(2);
+
+// 运算后的 myFish: ["angel", "clown"]
+// 被删除的元素: ["mandarin", "sturgeon"]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.4.4.12', 'Array.prototype.splice')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-array.prototype.splice', 'Array.prototype.splice')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-array.prototype.splice', 'Array.prototype.splice')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.splice")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/tolocalestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/tolocalestring/index.html new file mode 100644 index 0000000000..38b9c01c94 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/tolocalestring/index.html @@ -0,0 +1,177 @@ +--- +title: Array.prototype.toLocaleString() +slug: Web/JavaScript/Reference/Global_Objects/Array/toLocaleString +tags: + - Array + - JavaScript + - Method +translation_of: Web/JavaScript/Reference/Global_Objects/Array/toLocaleString +--- +
{{JSRef("Global_Objects", "Array")}}
+ +

toLocaleString() 返回一个字符串表示数组中的元素。数组中的元素将使用各自的 toLocaleString 方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号 ",")隔开。

+ +
{{EmbedInteractiveExample("pages/js/array-tolocalestring.html")}}
+ +

语法

+ +
arr.toLocaleString([locales[,options]]);
+ +

参数

+ +
+
locales {{optional_inline}}
+
带有BCP 47语言标记的字符串或字符串数组,关于locales参数的形式与解释,请看{{jsxref("Intl")}}页面。
+
options {{optional_inline}}
+
一个可配置属性的对象,对于数字 {{jsxref("Number.prototype.toLocaleString()")}},对于日期{{jsxref("Date.prototype.toLocaleString()")}}.
+
+ +

返回值

+ +

表示数组元素的字符串。

+ +

示例

+ +

使用localesoptions

+ +

数组中的元素将会使用各自的 toLocaleString 方法:

+ + + +

总是在prices数组中显示字符串和数字的货币符号:

+ +
var prices = ['¥7', 500, 8123, 12];
+prices.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' });
+
+// "¥7,¥500,¥8,123,¥12"
+ +

更多实例请看 {{jsxref("Intl")}},{{jsxref("NumberFormat")}}和{{jsxref("DateTimeFormat")}}页面。

+ +

Polyfill

+ +
// https://tc39.github.io/ecma402/#sup-array.prototype.tolocalestring
+if (!Array.prototype.toLocaleString) {
+  Object.defineProperty(Array.prototype, 'toLocaleString', {
+    value: function(locales, options) {
+      // 1. Let O be ? ToObject(this value).
+      if (this == null) {
+        throw new TypeError('"this" is null or not defined');
+      }
+
+      var a = Object(this);
+
+      // 2. Let len be ? ToLength(? Get(A, "length")).
+      var len = a.length >>> 0;
+
+      // 3. Let separator be the String value for the
+      //    list-separator String appropriate for the
+      //    host environment's current locale (this is
+      //    derived in an implementation-defined way).
+      // NOTE: In this case, we will use a comma
+      var separator = ',';
+
+      // 4. If len is zero, return the empty String.
+      if (len === 0) {
+        return '';
+      }
+
+      // 5. Let firstElement be ? Get(A, "0").
+      var firstElement = a[0];
+      // 6. If firstElement is undefined or null, then
+      //  a.Let R be the empty String.
+      // 7. Else,
+      //  a. Let R be ?
+      //     ToString(?
+      //       Invoke(
+      //        firstElement,
+      //        "toLocaleString",
+      //        « locales, options »
+      //       )
+      //     )
+      var r = firstElement == null ?
+        '' : firstElement.toLocaleString(locales, options);
+
+      // 8. Let k be 1.
+      var k = 1;
+
+      // 9. Repeat, while k < len
+      while (k < len) {
+        // a. Let S be a String value produced by
+        //   concatenating R and separator.
+        var s = r + separator;
+
+        // b. Let nextElement be ? Get(A, ToString(k)).
+        var nextElement = a[k];
+
+        // c. If nextElement is undefined or null, then
+        //   i. Let R be the empty String.
+        // d. Else,
+        //   i. Let R be ?
+        //     ToString(?
+        //       Invoke(
+        //        nextElement,
+        //        "toLocaleString",
+        //        « locales, options »
+        //       )
+        //     )
+        r = nextElement == null ?
+          '' : nextElement.toLocaleString(locales, options);
+
+        // e. Let R be a String value produced by
+        //   concatenating S and R.
+        r = s + r;
+
+        // f. Increase k by 1.
+        k++;
+      }
+
+      // 10. Return R.
+      return r;
+    }
+  });
+}
+
+ +

如果你需要支持真正不支持Object.defineProperty的JavaScript引擎,最好不要对Array.prototype方法进行填充,因为你不能使它们不可枚举。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-array.prototype.tolocalestring', 'Array.prototype.toLocaleString')}}{{Spec2('ESDraft')}}Initial definition was in ECMAScript 3.
{{SpecName('ES Int Draft', '#sup-array.prototype.tolocalestring', 'Array.prototype.toLocaleString')}}{{Spec2('ES Int Draft')}}This definition supersedes the definition provided in ECMA-262.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.toLocaleString")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/tosource/index.html new file mode 100644 index 0000000000..7ff8cff304 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/tosource/index.html @@ -0,0 +1,40 @@ +--- +title: Array.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/Array/toSource +translation_of: Web/JavaScript/Reference/Global_Objects/Array/toSource +--- +

{{JSRef("Global_Objects", "Array")}}{{Non-standard_header}}

+ +

概述

+ +

返回一个字符串,代表该数组的源代码.

+ +

语法

+ +
array.toSource()
+ +

参数

+ +

+ +

描述

+ +

在调试时,你可以使用toSource方法来查看一个数组的内容.

+ +

例子

+ +

例子: 查看数组的源码

+ +
var alpha = new Array("a", "b", "c");
+
+alpha.toSource();   //返回["a", "b", "c"]
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Array.toSource")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/tostring/index.html new file mode 100644 index 0000000000..9d49798a94 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/tostring/index.html @@ -0,0 +1,80 @@ +--- +title: Array.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/Array/toString +tags: + - Array + - JavaScript + - Method +translation_of: Web/JavaScript/Reference/Global_Objects/Array/toString +--- +
{{JSRef("Global_Objects", "Array")}}
+ +

toString() 返回一个字符串,表示指定的数组及其元素。

+ +
{{EmbedInteractiveExample("pages/js/array-tostring.html")}}
+ +

语法

+ +
arr.toString()
+
+ +

返回值

+ +

一个表示指定的数组及其元素的字符串。

+ +

描述

+ +

{{jsxref("Array")}}对象覆盖了{{jsxref("Object")}}的 toString 方法。对于数组对象,toString 方法连接数组并返回一个字符串,其中包含用逗号分隔的每个数组元素。

+ +

当一个数组被作为文本值或者进行字符串连接操作时,将会自动调用其 toString 方法。

+ +

ECMAScript 5 semantics

+ +

从 JavaScript 1.8.5 (Firefox 4) 开始,和 ECMAScript 第5版语义(semantics)一致,toString() 方法是通用的,可被用于任何对象。将调用{{jsxref("Object.prototype.toString()")}},并返回结果值。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.4.4.2', 'Array.prototype.toString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-array.prototype.tostring', 'Array.prototype.toString')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-array.prototype.tostring', 'Array.prototype.toString')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.toString")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/unobserve/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/unobserve/index.html new file mode 100644 index 0000000000..90678a1081 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/unobserve/index.html @@ -0,0 +1,86 @@ +--- +title: Array.unobserve() +slug: Web/JavaScript/Reference/Global_Objects/Array/unobserve +translation_of: Archive/Web/JavaScript/Array.unobserve +--- +
{{JSRef}} {{non-standard_header}}
+ +

Array.unobserve()方法用来移除{{jsxref("Array.observe()")}}设置的所有观察者。

+ +

语法

+ +
Array.unobserve(arr, callback)
+ +

参数

+ +
+
arr
+
停止观察的数组。
+
 
+
callback回调
+
需要停止的array arr每次改变都会调用的函数引用。
+
+ +

描述

+ +

Array.unobserve() 方法因为要移除观察者,所以应该在{{jsxref("Array.observe()")}}调用后调用。

+ +

回调函数应该是一个函数的引用并且不能是匿名函数, 因为这个函数需要用来移除前面的观察者, 如果用匿名函数是没有用的,将不能移除任何观察者。

+ +

例子

+ +

停止观察一个数组

+ +
var arr = [1, 2, 3];
+
+var observer = function(changes) {
+  console.log(changes);
+}
+
+Array.observe(arr, observer);
+​
+arr.push(4);
+// [{type: "splice", object: <arr>, index: 3, removed:[], addedCount: 1}]
+
+Array.unobserve(arr, observer);
+
+arr.pop();
+// The callback wasn't called
+ +

使用匿名函数

+ +
var persons = ['Khalid', 'Ahmed', 'Mohammed'];
+
+Array.observe(persons, function (changes) {
+  console.log(changes);
+});
+
+persons.shift();
+// [{type: "splice", object: <arr>, index: 0, removed: [ "Khalid" ], addedCount: 0 }]
+
+Array.unobserve(persons, function (changes) {
+  console.log(changes);
+});
+
+persons.push('Abdullah');
+// [{type: "splice", object: <arr>, index: 2, removed: [], addedCount: 1 }]
+// The callback will always be called
+
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Array.unobserve")}}

+
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/unshift/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/unshift/index.html new file mode 100644 index 0000000000..7b1148813f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/unshift/index.html @@ -0,0 +1,120 @@ +--- +title: Array.prototype.unshift() +slug: Web/JavaScript/Reference/Global_Objects/Array/unshift +tags: + - Array + - JavaScript + - Method + - 原型 + - 参考资料 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/unshift +--- +

{{JSRef}}

+ +

unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)

+ +
{{EmbedInteractiveExample("pages/js/array-unshift.html")}}
+ +

语法

+ +
arr.unshift(element1, ..., elementN)
+
+ +

参数列表

+ +
+
elementN
+
要添加到数组开头的元素或多个元素。
+
+ +

返回值

+ +

当一个对象调用该方法时,返回其 {{jsxref("Array.length", "length")}} 属性值。

+ +
+
+ +

描述

+ +

unshift 方法会在调用它的类数组对象的开始位置插入给定的参数。

+ +

unshift 特意被设计成具有通用性;这个方法能够通过 {{jsxref("Function.call", "call")}} 或 {{jsxref("Function.apply", "apply")}} 方法作用于类数组对象上。不过对于没有 length 属性(代表从0开始的一系列连续的数字属性的最后一个)的对象,调用该方法可能没有任何意义。

+ +

注意, 如果传入多个参数,它们会被以块的形式插入到对象的开始位置,它们的顺序和被作为参数传入时的顺序一致。 于是,传入多个参数调用一次 unshift ,和传入一个参数调用多次 unshift (例如,循环调用),它们将得到不同的结果。例如:

+ +
let arr = [4,5,6];
+arr.unshift(1,2,3);
+console.log(arr); // [1, 2, 3, 4, 5, 6]
+
+arr = [4,5,6]; // 重置数组
+arr.unshift(1);
+arr.unshift(2);
+arr.unshift(3);
+console.log(arr); // [3, 2, 1, 4, 5, 6]
+
+ +

示例

+ +
let arr = [1, 2];
+
+arr.unshift(0); // result of the call is 3, which is the new array length
+// arr is [0, 1, 2]
+
+arr.unshift(-2, -1); // the new array length is 5
+// arr is [-2, -1, 0, 1, 2]
+
+arr.unshift([-4, -3]); // the new array length is 6
+// arr is [[-4, -3], -2, -1, 0, 1, 2]
+
+arr.unshift([-7, -6], [-5]); // the new array length is 8
+// arr is [ [-7, -6], [-5], [-4, -3], -2, -1, 0, 1, 2 ]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.4.4.13', 'Array.prototype.unshift')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-array.prototype.unshift', 'Array.prototype.unshift')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.unshift', 'Array.prototype.unshift')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.unshift")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/values/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/values/index.html new file mode 100644 index 0000000000..cf9b1c7c82 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/values/index.html @@ -0,0 +1,125 @@ +--- +title: Array.prototype.values() +slug: Web/JavaScript/Reference/Global_Objects/Array/values +tags: + - Array + - ECMAScript 2015 + - Iterator + - JavaScript + - Prototype + - 数组 + - 方法 + - 迭代 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/values +--- +
{{JSRef}}
+ +

values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值

+ +
{{EmbedInteractiveExample("pages/js/array-values.html")}}
+ +

语法

+ +
arr.values()
+ +

返回值

+ +

一个新的 {{jsxref("Array")}} 迭代对象。

+ +

示例

+ +

使用 for...of 循环进行迭代

+ +
let arr = ['w', 'y', 'k', 'o', 'p'];
+let eArr = arr.values();
+
+for (let letter of eArr) {
+  console.log(letter);
+} //"w" "y "k" "o" "p"
+ +

Array.prototype.values 是 Array.prototype[Symbol.iterator] 的默认实现。

+ +
Array.prototype.values === Array.prototype[Symbol.iterator]  // true 
+ +

使用 .next() 迭代

+ +
var arr = ['a', 'b', 'c', 'd', 'e'];
+var iterator = arr.values();
+iterator.next();               // Object { value: "a", done: false }
+iterator.next().value;         // "b"
+iterator.next()["value"];      // "c"
+iterator.next();               // Object { value: "d", done: false }
+iterator.next();               // Object { value: "e", done: false }
+iterator.next();               // Object { value: undefined, done: true }
+iteraroe.next().value;         // undefined
+ +
+

一次性:数组迭代器是一次性的,或者说临时对象

+
+ +

例子:

+ +
var arr = ['a', 'b', 'c', 'd', 'e'];
+ var iterator = arr.values();
+ for (let letter of iterator) {
+ console.log(letter);
+} //"a" "b" "c" "d"
+for (let letter of iterator) {
+console.log(letter);
+} // undefined
+ +

解释: 当 next().done=true 或 currentIndex>length 时, for..of 循环结束。参见 Iteration protocols 。

+ +

: 数组迭代器中存储的是原数组的地址,而不是数组元素值。

+ +
var arr = ['a', 'b', 'c', 'd', 'e'];
+var iterator = arr.values();
+console.log(iterator); // Array Iterator {  }
+iterator.next().value; // "a"
+arr[1] = 'n';
+iterator.next().value; //  "n"
+
+ +
+

如果数组中元素改变,那么迭代器的值也会改变

+
+ + + +

规范

+ + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES6', '#sec-array.prototype.values', 'Array.prototype.values')}}{{Spec2('ES6')}}首次定义
{{SpecName('ESDraft', '#sec-array.prototype.values', 'Array.prototype.values')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Array.values")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/@@species/index.html b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/@@species/index.html new file mode 100644 index 0000000000..fe99f2b076 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/@@species/index.html @@ -0,0 +1,70 @@ +--- +title: 'get ArrayBuffer[@@species]' +slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/@@species +tags: + - ArrayBuffer + - JavaScript + - TypedArrays + - 属性 +translation_of: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/@@species +--- +
{{JSRef}}
+ +

该 ArrayBuffer[@@species] 访问器属性会返回 ArrayBuffer 构造器。

+ +

语法

+ +
ArrayBuffer[Symbol.species]
+
+ +

描述

+ +

这个 species 访问器属性会返回默认的 ArrayBuffer 构造器。子类构造器可能会覆盖它以改变构造器赋值。

+ +

示例

+ +

返回默认的 ArrayBuffer 构造器:

+ +
ArrayBuffer[Symbol.species]; // function ArrayBuffer()
+ +

在派生集合对象中(比如你定制的 array buffer MyArrayBuffer),MyArrayBuffer species 就是 MyArrayBuffer 构造器。但是,你可能想要在派生类里重写它,以期返回的是父类的 ArrayBuffer 对象:

+ +
class MyArrayBuffer extends ArrayBuffer {
+  // Overwrite MyArrayBuffer species to the parent ArrayBuffer constructor
+  static get [Symbol.species]() { return ArrayBuffer; }
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-arraybuffer-@@species', 'get ArrayBuffer [ @@species ]')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-get-arraybuffer-@@species', 'get ArrayBuffer [ @@species ]')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.ArrayBuffer.@@species")}}

+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/bytelength/index.html b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/bytelength/index.html new file mode 100644 index 0000000000..af8868a563 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/bytelength/index.html @@ -0,0 +1,62 @@ +--- +title: ArrayBuffer.prototype.byteLength +slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength +translation_of: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength +--- +
{{JSRef}}
+ +

byteLength访问器属性表示一个{{jsxref("ArrayBuffer")}} 对象的字节长度。

+ +
{{EmbedInteractiveExample("pages/js/arraybuffer-bytelength.html")}}
+ + + +

语法

+ +
arraybuffer.byteLength
+ +

描述

+ +

byteLength属性是一个访问器属性,它的set访问器函数是undefined,这意味着你只能读这个属性。 该值在数组创建时确定,并且不可变更。如果这个ArrayBuffer 被移除,则此属性返回0。

+ +

 

+ +

示例

+ +
var buffer = new ArrayBuffer(8);
+buffer.byteLength; // 8
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-get-arraybuffer.prototype.bytelength', 'ArrayBuffer.prototype.byteLength')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.ArrayBuffer.byteLength")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/index.html b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/index.html new file mode 100644 index 0000000000..a98aca4290 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/index.html @@ -0,0 +1,161 @@ +--- +title: ArrayBuffer +slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer +tags: + - ArrayBuffer + - JavaScript + - 构造函数 + - 类型数组 +translation_of: Web/JavaScript/Reference/Global_Objects/ArrayBuffer +--- +
+

{{JSRef}}

+ +

ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。

+ +

它是一个字节数组,通常在其他语言中称为“byte array”。

+ +

你不能直接操作 ArrayBuffer 的内容,而是要通过类型数组对象或 {{jsxref("DataView")}} 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。

+
+ +
{{EmbedInteractiveExample("pages/js/arraybuffer-constructor.html")}}
+ + + +

语法

+ +
new ArrayBuffer(length)
+
+ +

参数

+ +
+
length
+
要创建的 ArrayBuffer 的大小,单位为字节。
+
+ +

返回值

+ +

一个指定大小的 ArrayBuffer 对象,其内容被初始化为 0。

+ +

异常

+ +

如果 length 大于 {{jsxref("Number.MAX_SAFE_INTEGER")}}(>= 2 ** 53)或为负数,则抛出一个  {{jsxref("RangeError")}}  异常。

+ +

描述

+ +

ArrayBuffer 构造函数用来创建一个指定字节长度的 ArrayBuffer 对象。

+ +

以现有数据获取 ArrayBuffer

+ + + +

属性

+ +
+
ArrayBuffer.length
+
ArrayBuffer 构造函数的 length 属性,其值为1。
+
+ +
+
{{jsxref("ArrayBuffer.prototype.byteLength")}}
+
只读属性,表示 ArrayBuffer 的byte的大小,在ArrayBuffer构造完成时生成,不可改变。
+
+ +
+
{{jsxref("ArrayBuffer.@@species", "get ArrayBuffer[@@species]")}}
+
返回 ArrayBuffer 的构造函数。
+
{{jsxref("ArrayBuffer.prototype")}}
+
通过 ArrayBuffer 的原型对象可以为所有 ArrayBuffer 对象添加属性。
+
+ +

方法

+ +
+
{{jsxref("ArrayBuffer.isView", "ArrayBuffer.isView(arg)")}}
+
如果参数是 ArrayBuffer 的视图实例则返回 true,例如 类型数组对象 或 {{jsxref("DataView")}} 对象;否则返回 false
+
{{jsxref("ArrayBuffer.transfer", "ArrayBuffer.transfer(oldBuffer [, newByteLength])")}} {{experimental_inline}}
+
+

返回一个新的 ArrayBuffer 对象,其内容取自 oldBuffer 中的数据,并且根据 newByteLength 的大小对数据进行截取或补 0。

+
+
+ +

ArrayBuffer 实例

+ +

所有 ArrayBuffer 实例都会从 {{jsxref("ArrayBuffer.prototype")}} 继承属性和方法。

+ +

属性

+ +

{{page('zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype','属性')}}

+ +

方法

+ +

{{page('zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype','方法')}}

+ +
+
{{jsxref("ArrayBuffer.slice()")}} {{non-standard_inline}}
+
和 {{jsxref("ArrayBuffer.prototype.slice()")}} 功能相同。
+
+ +

示例

+ +

下面的例子创建了一个 8 字节的缓冲区,并使用一个 {{jsxref("Global_Objects/Int32Array", "Int32Array")}} 来引用它:

+ +
var buffer = new ArrayBuffer(8);
+var view   = new Int32Array(buffer);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}已被 ECMAScript 6 中的 ArrayBuffer 取代
{{SpecName('ES6', '#sec-arraybuffer-constructor', 'ArrayBuffer')}}{{Spec2('ES6')}}在 ECMA 标准中的初始定义。规定了必须通过 new 来调用构造函数
{{SpecName('ESDraft', '#sec-arraybuffer-constructor', 'ArrayBuffer')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.ArrayBuffer")}}

+ +

兼容性提醒

+ +

从 ECMAScript 2015 开始,ArrayBuffer 对象需要用 {{jsxref("Operators/new", "new")}} 运算符创建。如果调用构造函数时没有使用 new,将会抛出 {{jsxref("TypeError")}}  异常。

+ +
var dv = ArrayBuffer(10);
+// TypeError: calling a builtin ArrayBuffer constructor
+// without new is forbidden
+ +
var dv = new ArrayBuffer(10);
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/isview/index.html b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/isview/index.html new file mode 100644 index 0000000000..2b545d9c03 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/isview/index.html @@ -0,0 +1,87 @@ +--- +title: ArrayBuffer.isView() +slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView +tags: + - 类型数组 + - 缓冲区 +translation_of: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView +--- +
{{JSRef}}
+ +

ArrayBuffer.isView() 方法用来判断传入的参数值是否是一种 ArrayBuffer 视图(view),比如类型化数组对象(typed array objects)或者数据视图( {{jsxref("DataView")}})。

+ +
{{EmbedInteractiveExample("pages/js/arraybuffer-isview.html")}}
+ + + +

语法

+ +
ArrayBuffer.isView(value)
+ +

参数

+ +
+
value
+
被检测的值。
+
+ +

返回值

+ +
+
true
+
如果提供的参数是一种 {{jsxref("ArrayBuffer")}} 视图;
+
false
+
提供的参数不是一种 {{jsxref("ArrayBuffer")}} 视图类型;
+
+ +

示例

+ +
ArrayBuffer.isView();                    // false
+ArrayBuffer.isView([]);                  // false
+ArrayBuffer.isView({});                  // false
+ArrayBuffer.isView(null);                // false
+ArrayBuffer.isView(undefined);           // false
+ArrayBuffer.isView(new ArrayBuffer(10)); // false
+
+ArrayBuffer.isView(new Uint8Array());    // true
+ArrayBuffer.isView(new Float32Array());  // true
+ArrayBuffer.isView(new Int8Array(10).subarray(0, 3)); // true
+
+var buffer = new ArrayBuffer(2);
+var dv = new DataView(buffer);
+ArrayBuffer.isView(dv); // true
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-arraybuffer.isview', 'ArrayBuffer.isView')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.ArrayBuffer.isView")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/prototype/index.html new file mode 100644 index 0000000000..376e969064 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/prototype/index.html @@ -0,0 +1,63 @@ +--- +title: ArrayBuffer.prototype +slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype +tags: + - ArrayBuffer +translation_of: Web/JavaScript/Reference/Global_Objects/ArrayBuffer +--- +
{{JSRef}}
+ +

ArrayBuffer.prototype属性表示{{jsxref("ArrayBuffer")}}对象的原型。

+ +
{{js_property_attributes(0,0,0)}}
+ +
 
+ +

描述

+ +

ArrayBuffer 实例继承自ArrayBuffer.prototype。对所有的构造函数来说,你可以通过改变构造函数的原型对象来改变所有的ArrayBuffer实例。

+ +

属性

+ +
+
ArrayBuffer.prototype.constructor
+
指定函数,它创建一个对象的原型。其初始值是标准ArrayBuffer内置构造函数。
+
{{jsxref("ArrayBuffer.prototype.byteLength")}} {{readonlyInline}}
+
数组的字节大小。在数组创建时确定,并且不可变更。只读
+
+ +

方法

+ +
+
{{jsxref("ArrayBuffer.prototype.slice()")}}
+
返回一个新的 ArrayBuffer ,它的内容是这个 ArrayBuffer 的字节副本,从begin(包括),到end(不包括)。如果begin或end是负数,则指的是从数组末尾开始的索引,而不是从头开始。
+
+ +

规范

+ + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES6', '#sec-arraybuffer.prototype', 'ArrayBuffer.prototype')}}{{Spec2('ES6')}}初始定义
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.ArrayBuffer.prototype")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/slice/index.html b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/slice/index.html new file mode 100644 index 0000000000..2c03d1e13c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/slice/index.html @@ -0,0 +1,83 @@ +--- +title: ArrayBuffer.prototype.slice() +slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/slice +translation_of: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/slice +--- +
{{JSRef}}
+ +

slice()方法返回一个新的 ArrayBuffer ,它的内容是这个ArrayBuffer的字节副本,从begin(包括),到end(不包括)。

+ +
{{EmbedInteractiveExample("pages/js/arraybuffer-slice.html")}}
+ + + +

语法

+ +
arraybuffer.slice(begin[, end])
+ +

参数

+ +
+
begin
+
从零开始的字节索引,切片从这开始。
+
+ +
+
end
+
结束切片的字节索引。如果没指定end,新的 ArrayBuffer 将包含这个 ArrayBuffer 从头到尾的所有字节。由begin和end指定的这个范围夹在当前数组的有效索引范围内。如果新ArrayBuffer的长度在计算后为负,它将强制为0 。
+
+ +

返回值

+ +

 一个新的 ArrayBuffer 对象。

+ +

描述

+ +

slice 方法复制到但不包括由end参数指示的字节。如果begin或end是负数,则指的是从数组末尾开始的索引,而不是从头开始。

+ +

示例

+ +

复制一个 ArrayBuffer

+ +
var buf1 = new ArrayBuffer(8);
+var buf2 = buf1.slice(0);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by EMCAScript 6.
{{SpecName('ES6', '#sec-arraybuffer.prototype.slice', 'ArrayBuffer.prototype.slice')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-arraybuffer.prototype.slice', 'ArrayBuffer.prototype.slice')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.ArrayBuffer.slice")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/transfer/index.html b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/transfer/index.html new file mode 100644 index 0000000000..cf3185f637 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/transfer/index.html @@ -0,0 +1,116 @@ +--- +title: ArrayBuffer.transfer() +slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/transfer +translation_of: Archive/Web/JavaScript/ArrayBuffer.transfer +--- +
{{JSRef}} {{SeeCompatTable}}
+ +

 静态ArrayBuffer.transfer() 方法返回一个新的ArrayBuffer, 其内容取自oldBuffer的数据,并且根据 newByteLength 的大小来对数据进行截取或者以0扩展。 如果 newByteLength 未定义,则使用 oldBuffer 的byteLength。这个操作使得 oldBuffer 处于被移除的状态。

+ +

语法

+ +
ArrayBuffer.transfer(oldBuffer [, newByteLength]);
+ +

参数

+ +
+
oldBuffer
+
 要转移的{{jsxref("ArrayBuffer")}}对象。
+
newByteLength
+
ArrayBuffer 对象的字节长度。
+
+ +

返回值

+ +

一个新的ArrayBuffer对象。

+ +

描述

+ +

ArrayBuffer.transfer()方法允许你增长和移除 ArrayBuffer 对象。不需复制就能增长一个ArrayBuffer的功能,对于大的缓冲区来说,有速度优势 (类似realloc) 。当释放底层内存时,移除ArrayBuffer的功能给开发者提供了显式控制。这避免了必须丢弃所有引用和等待垃圾回收。

+ +

示例

+ +
var buf1 = new ArrayBuffer(40);
+new Int32Array(buf1)[0] = 42;
+
+var buf2 = ArrayBuffer.transfer(buf1, 80);
+buf1.byteLength; // 0 but if you use the polyfill then the value is still 40
+buf2.byteLength; // 80
+new Int32Array(buf2)[0]; // 42
+
+var buf3 = ArrayBuffer.transfer(buf2, 0);
+buf2.byteLength; // 0 but if you use the polyfill then the value is still 80
+buf3.byteLength; // 0
+
+ +

Polyfill

+ +

You can partially work around this by inserting the following code at the beginning of your scripts, allowing use of much of the functionality of transfer() in implementations that do not natively support it. This is not the exact equivalent of this API, but this function transfers data from one ArrayBuffer to another ArrayBuffer.

+ +
if(!ArrayBuffer.transfer) {
+    ArrayBuffer.transfer = function (source, length) {
+        source = Object(source);
+        var dest = new ArrayBuffer(length);
+        if(!(source instanceof ArrayBuffer) || !(dest instanceof ArrayBuffer)) {
+            throw new TypeError("Source and destination must be ArrayBuffer instances");
+        }
+        if(dest.byteLength >= source.byteLength) {
+            var nextOffset = 0;
+            var leftBytes = source.byteLength;
+            var wordSizes = [8, 4, 2, 1];
+            wordSizes.forEach(function (_wordSize_) {
+                if (leftBytes >= _wordSize_) {
+                    var done = transferWith(_wordSize_, source, dest, nextOffset, leftBytes);
+                    nextOffset = done.nextOffset;
+                    leftBytes = done.leftBytes;
+                }
+            });
+        }
+        return dest;
+        function transferWith(wordSize, source, dest, nextOffset, leftBytes) {
+            var ViewClass = Uint8Array;
+            switch (wordSize)  {
+                case 8:
+                    ViewClass = Float64Array;
+                    break;
+                case 4:
+                    ViewClass = Float32Array;
+                    break;
+                case 2:
+                    ViewClass = Uint16Array;
+                    break;
+                case 1:
+                    ViewClass = Uint8Array;
+                    break;
+                default:
+                    ViewClass = Uint8Array;
+                    break;
+            }
+            var view_source = new ViewClass(source, nextOffset, Math.trunc(leftBytes / wordSize));
+            var view_dest = new ViewClass(dest, nextOffset, Math.trunc(leftBytes / wordSize));
+            for(var i=0; i<view_dest.length; i++) {
+                view_dest[i] = view_source[i];
+            }
+            return {
+                nextOffset : view_source.byteOffset + view_source.byteLength,
+                leftBytes : source.byteLength - (view_source.byteOffset + view_source.byteLength)
+            }
+        }
+    };
+}
+ +

规范

+ +

Not part of any current specification draft document, but has been proposed for a future ECMA-262 edition.

+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.ArrayBuffer.transfer")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/asyncfunction/index.html b/files/zh-cn/web/javascript/reference/global_objects/asyncfunction/index.html new file mode 100644 index 0000000000..e24d75c33f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/asyncfunction/index.html @@ -0,0 +1,121 @@ +--- +title: AsyncFunction +slug: Web/JavaScript/Reference/Global_Objects/AsyncFunction +tags: + - JavaScript + - Reference + - 实验性内容 + - 构造函数 +translation_of: Web/JavaScript/Reference/Global_Objects/AsyncFunction +--- +
{{JSRef}}
+ +
 
+ +

AsyncFunction 构造函数用来创建新的 {{jsxref("Statements/async_function", "异步函数")}} 对象,JavaScript 中每个异步函数都是  AsyncFunction 的对象。

+ +

注意,AsyncFunction 并不是一个全局对象,需要通过下面的方法来获取:

+ +
Object.getPrototypeOf(async function(){}).constructor
+
+ +

语法

+ +
new AsyncFunction([arg1[, arg2[, ...argN]],] functionBody)
+ +

参数

+ +
+
arg1, arg2, ... argN
+
函数的参数名,它们是符合 JavaScript 标示符规范的一个或多个用逗号隔开的字符串。例如 xtheValue、或 a,b
+
functionBody
+
一段字符串形式的 JavaScript 语句,这些语句组成了新函数的定义。
+
+ +

描述

+ +

执行 AsyncFunction 构造函数的时候,会创建一个 {{jsxref("Statements/async_function", "异步函数")}} 对象。但是这种方式不如先用 {{jsxref("Operators/async_function", "异步函数表达式")}} 定义一个异步函数,然后再调用其来创建 {{jsxref("Statements/async_function", "异步函数")}} 对象来的高效,因为第二种方式中异步函数是与其他代码一起被解释器解析的,而第一种方式的函数体是单独解析的。

+ +

传递给 AsyncFunction 构造函数的所有参数,都会成为新函数中的变量,变量的名称和定义顺序与各参数相同。 

+ +
+

注意:使用 AsyncFunction 构造函数创建的{{jsxref("Statements/async_function", "异步函数")}} 并不会在当前上下文中创建闭包,其作用域始终是全局的。因此运行的时候只能访问它们自己的本地变量和全局变量,但不能访问构造函数被调用的那个作用域中的变量。这是它与 {{jsxref("Global_Objects/eval", "eval")}} 不同的地方。

+
+ +

调用 AsyncFunction 构造函数时可以省略 new,其效果是一样的。

+ +

属性

+ +
+
AsyncFunction.length
+
AsyncFunction 构造函数的 length 属性,值为 1。
+
{{jsxref("AsyncFunction.prototype")}}
+
通过原型对象可以为所有异步函数对象定义额外的属性。
+
+ +

AsyncFunction 原型对象

+ +

属性

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype', '属性')}}
+ +

AsyncFunction 实例

+ +

AsyncFunction 实例继承了 {{jsxref("AsyncFunction.prototype")}} 的方法和属性。和所有构造函数一样,修改 AsyncFunction 构造函数的原型对象会同时对所有 AsyncFunction 实例上生效。

+ +

示例

+ +

通过 AsyncFunction 构造器创建一个异步函数

+ +
function resolveAfter2Seconds(x) {
+  return new Promise(resolve => {
+    setTimeout(() => {
+      resolve(x);
+    }, 2000);
+  });
+}
+
+var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
+var a = new AsyncFunction('a',
+                          'b',
+                          'return await resolveAfter2Seconds(a) + await resolveAfter2Seconds(b);');
+a(10, 20).then(v => {
+  console.log(v); // 4 秒后打印 30
+});
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-objects', 'AsyncFunction object')}}{{Spec2('ESDraft')}}ES2017 中的初始定义
+ +

浏览器兼容性

+ + + +
{{Compat("javascript.builtins.AsyncFunction")}}
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/asyncfunction/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/asyncfunction/prototype/index.html new file mode 100644 index 0000000000..9a8678680a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/asyncfunction/prototype/index.html @@ -0,0 +1,57 @@ +--- +title: AsyncFunction.prototype +slug: Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype +--- +
{{JSRef}}
+ +

AsyncFunction.prototype 属性表示 {{jsxref("AsyncFunction")}} 的原型对象。

+ +

描述

+ +

{{jsxref("AsyncFunction")}} 对象继承自 AsyncFunction.prototypeAsyncFunction.prototype 不能被修改。

+ +

属性

+ +
+
AsyncFunction.constructor
+
默认值为 {{jsxref("AsyncFunction")}}。
+
AsyncFunction.prototype[@@toStringTag]
+
返回 "AsyncFunction"。
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-constructor-prototype', 'AsyncFunction.prototype')}}{{Spec2('ESDraft')}}最初定义在ES2017.
+ +

兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.AsyncFunction.prototype")}}

+
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/asynciterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/asynciterator/index.html new file mode 100644 index 0000000000..9c14e462bd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/asynciterator/index.html @@ -0,0 +1,119 @@ +--- +title: AsyncIterator +slug: Web/JavaScript/Reference/Global_Objects/AsyncIterator +tags: + - 异步迭代器 + - 类 +translation_of: Web/JavaScript/Reference/Global_Objects/AsyncIterator +--- +

{{JSRef}}{{Draft}}

+ +

AsyncIterator 全局对象是一个提供辅助方法的抽象类,与暴露在{{JSxRef("Array")}} 实例上的那些类似。

+ +

构造函数

+ +
+
{{JSxRef("AsyncIterator.AsyncIterator", "AsyncIterator()")}} 
+
一个抽象构造函数,仅能够通过 {{JSxRef("Operators/super", "super()")}} 来调用。
+
+ +

属性

+ +
+
AsyncIterator.prototype
+
%AsyncIteratorPrototype% 内部对象。
+
+ +

方法

+ +
+
{{JSxRef("AsyncIterator.from()")}} 
+
等同于在传入的对象上调用 @@asyncIterator 。
+
+ +

AsyncIterator 原型

+ +

原型属性

+ +
+
AsyncIterator.prototype.constructor
+
指定创建对的象原型的函数.
+
AsyncIterator.prototype[@@toStringTag] 
+
字符串 "Iterator".
+
+ +

原型方法

+ +
+
{{JSxRef("AsyncIterator.prototype.map()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.filter()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.take()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.drop()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.asIndexedPairs()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.flatMap()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.reduce()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.toArray()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.forEach()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.some()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.every()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.find()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.@@iterator()", "AsyncIterator.prototype[@@iterator]()")}}
+
返回该 AsyncIterator 实例。
+
+ +

实现方法

+ +
+
{{JSxRef("AsyncIterator.prototype.next()", "<implementation>.prototype.next()")}}
+
获取 AsyncIterator 中的下一项
+
{{JSxRef("AsyncIterator.prototype.return()", "<implementation>.prototype.next()")}}{{Optional_Inline}}
+
返回给出的值,并结束迭代。
+
{{JSxRef("AsyncIterator.prototype.throw()", "<implementation>.prototype.next()")}}{{Optional_Inline}}
+
抛出一个迭代器错误(同时也终止了迭代器,除非是在该迭代器内部被捕获)。
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
ESNext Iterator Helpers ProposalStage 2 DraftInitial definition
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.AsyncIterator")}}

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/add/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/add/index.html new file mode 100644 index 0000000000..256ddc4019 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/add/index.html @@ -0,0 +1,84 @@ +--- +title: Atomics.add() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/add +tags: + - Atomics + - JavaScript + - Shared Memory + - 共享内存 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/add +--- +
{{JSRef}}
+ +

Atomics.add() 静态方法会将给定的值加到数组里的某个特定位置上,并返回该位置的旧值。此原子操作保证在写上修改的值之前不会发生其他写操作。

+ +
{{EmbedInteractiveExample("pages/js/atomics-add.html")}}
+ + + +

语法

+ +
Atomics.add(typedArray, index, value)
+
+ +

参数

+ +
+
typedArray
+
一个共享的整型 typed array。例如 {{jsxref("Int8Array")}},{{jsxref("Uint8Array")}},{{jsxref("Int16Array")}},{{jsxref("Uint16Array")}},{{jsxref("Int32Array")}},或者 {{jsxref("Uint32Array")}}。
+
index
+
typedArray 中的位置,该位置数值会被加总并更新。
+
value
+
增加的数字。
+
+ +

返回值

+ +

给定位置的旧值(typedArray[index])

+ +

错误

+ + + +

示例

+ +
var sab = new SharedArrayBuffer(1024);
+var ta = new Uint8Array(sab);
+
+Atomics.add(ta, 0, 12); // returns 0, the old value
+Atomics.load(ta, 0); // 12
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-atomics.add', 'Atomics.add')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.Atomics.add")}}

+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/and/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/and/index.html new file mode 100644 index 0000000000..87754093bc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/and/index.html @@ -0,0 +1,130 @@ +--- +title: Atomics.and() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/and +tags: + - Atomics + - JavaScript + - 共享内存 + - 实验性 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/and +--- +
{{JSRef}} {{SeeCompatTable}}
+ +

Atomics.and() 静态方法会将给定的值与数组上的值进行按位与操作,并将结果赋值给数组,然后返回数组该位置上的旧值。此原子操作保证在写上修改的值之前不会发生其他写操作。

+ +
{{EmbedInteractiveExample("pages/js/atomics-and.html")}}
+ + + +

语法

+ +
Atomics.and(typedArray, index, value)
+
+ +

参数

+ +
+
typedArray
+
一个共享的整型 typed array。例如 {{jsxref("Int8Array")}},{{jsxref("Uint8Array")}},{{jsxref("Int16Array")}},{{jsxref("Uint16Array")}},{{jsxref("Int32Array")}},或 {{jsxref("Uint32Array")}}。
+
index
+
按位与操作的 typedArray 的值在数组上的索引。
+
value
+
给定的按位与操作的值。
+
+ +

返回值

+ +

给定位置的旧值(typedArray[index])。

+ +

错误

+ + + +

描述

+ +

假如 a 和 b 都是 1,那么按位与运算( a & b)仅产生1。与操作的真值表为:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba & b
000
010
100
111
+ +

比如,一个按位与如 5 & 1 的结果是 0001,其十进制就是1

+ +
5  0101
+1  0001
+   ----
+1  0001
+ +

示例

+ +
var sab = new SharedArrayBuffer(1024);
+var ta = new Uint8Array(sab);
+ta[0] = 5;
+
+Atomics.and(ta, 0, 1); // returns 0, the old value
+Atomics.load(ta, 0);  // 1
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Shared Memory', '#Atomics.and', 'Atomics.and')}}{{Spec2('Shared Memory')}}Initial definition.
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.Atomics.and")}}

+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/compareexchange/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/compareexchange/index.html new file mode 100644 index 0000000000..1883180411 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/compareexchange/index.html @@ -0,0 +1,86 @@ +--- +title: Atomics.compareExchange() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/compareExchange +tags: + - Atomics + - JavaScript + - 共享内存 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/compareExchange +--- +
{{JSRef}} {{SeeCompatTable}}
+ +

Atomics.compareExchange() 静态方法会在数组的值与期望值相等的时候,将给定的替换值替换掉数组上的值,然后返回旧值。此原子操作保证在写上修改的值之前不会发生其他写操作。

+ +
{{EmbedInteractiveExample("pages/js/atomics-compareexchange.html")}}
+ + + +

语法

+ +
Atomics.compareExchange(typedArray, index, expectedValue, replacementValue)
+
+ +

参数

+ +
+
typedArray
+
一个共享的整型 typed array。例如 {{jsxref("Int8Array")}},{{jsxref("Uint8Array")}},{{jsxref("Int16Array")}},{{jsxref("Uint16Array")}},{{jsxref("Int32Array")}},或 {{jsxref("Uint32Array")}}。
+
index
+
typedArray 的索引。
+
expectedValue
+
用于比较的值。
+
replacementValue
+
将要替换上的值。
+
+ +

返回值

+ +

给定位置的旧值(typedArray[index]).

+ +

错误

+ + + +

示例

+ +
var sab = new SharedArrayBuffer(1024);
+var ta = new Uint8Array(sab);
+ta[0] = 7;
+
+Atomics.compareExchange(ta, 0, 7, 12); // returns 7, the old value
+Atomics.load(ta, 0); // 12
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Shared Memory', '#Atomics.compareExchange', 'Atomics.compareExchange')}}{{Spec2('Shared Memory')}}Initial definition.
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.Atomics.compareExchange")}}

+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/exchange/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/exchange/index.html new file mode 100644 index 0000000000..4502bf8a52 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/exchange/index.html @@ -0,0 +1,85 @@ +--- +title: Atomics.exchange() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/exchange +tags: + - Atmoics + - Experimental + - JavaScript + - Method + - 共享内存 + - 实验性 +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/exchange +--- +
{{JSRef}} {{SeeCompatTable}}
+ +

Atomics.exchange() 静态方法会用给定的值替换掉数组上的值,然后返回数组的旧值。此原子操作保证在写上修改的值之前不会发生其他写操作。

+ +
{{EmbedInteractiveExample("pages/js/atomics-exchange.html")}}
+ + + +

语法

+ +
Atomics.exchange(typedArray, index, value)
+
+ +

参数

+ +
+
typedArray
+
一个共享的整型 typed array。例如 {{jsxref("Int8Array")}},{{jsxref("Uint8Array")}},{{jsxref("Int16Array")}},{{jsxref("Uint16Array")}},{{jsxref("Int32Array")}},或 {{jsxref("Uint32Array")}}。
+
index
+
被替换的 typedArray 值的索引。
+
value
+
去替换的值。
+
+ +

返回值

+ +

给定位置的旧值(typedArray[index]).

+ +

错误

+ + + +

示例

+ +
var sab = new SharedArrayBuffer(1024);
+var ta = new Uint8Array(sab);
+
+Atomics.exchange(ta, 0, 12); // returns 0, the old value
+Atomics.load(ta, 0); // 12
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Shared Memory', '#Atomics.exchange', 'Atomics.exchange')}}{{Spec2('Shared Memory')}}Initial definition.
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.Atomics.exchange")}}

+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/index.html new file mode 100644 index 0000000000..4c80b3f868 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/index.html @@ -0,0 +1,151 @@ +--- +title: Atomics +slug: Web/JavaScript/Reference/Global_Objects/Atomics +tags: + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics +--- +

{{JSRef}}

+ +

Atomics 对象提供了一组静态方法对 {{jsxref("SharedArrayBuffer")}} 和  {{jsxref("ArrayBuffer")}} 对象进行原子操作。

+ +

描述

+ +

这些原子操作属于 Atomics 模块。与一般的全局对象不同,Atomics 不是构造函数,因此不能使用 new 操作符调用,也不能将其当作函数直接调用。Atomics 的所有属性和方法都是静态的(与 {{jsxref("Math")}}  对象一样)。

+ +

原子操作

+ +

多个共享内存的线程能够同时读写同一位置上的数据。原子操作会确保正在读或写的数据的值是符合预期的,即下一个原子操作一定会在上一个原子操作结束后才会开始,其操作过程不会中断。

+ +

等待和通知

+ +

wait() 和 notify() 方法采用的是 Linux 上的 futexes 模型(“快速用户空间互斥量”),可以让进程一直等待直到某个特定的条件为真,主要用于实现阻塞。

+ +

方法

+ +
+
 
+
{{jsxref("Atomics.add()")}}
+
将指定位置上的数组元素与给定的值相加,并返回相加前该元素的值。
+
{{jsxref("Atomics.and()")}}
+
将指定位置上的数组元素与给定的值相与,并返回与操作前该元素的值。
+
{{jsxref("Atomics.compareExchange()")}}
+
如果数组中指定的元素与给定的值相等,则将其更新为新的值,并返回该元素原先的值。
+
{{jsxref("Atomics.exchange()")}}
+
将数组中指定的元素更新为给定的值,并返回该元素更新前的值。
+
{{jsxref("Atomics.isLockFree()", "Atomics.isLockFree(size)")}}
+
可以用来检测当前系统是否支持硬件级的原子操作。对于指定大小的数组,如果当前系统支持硬件级的原子操作,则返回 true;否则就意味着对于该数组,Atomics 对象中的各原子操作都只能用锁来实现。此函数面向的是技术专家。
+
{{jsxref("Atomics.load()")}}
+
返回数组中指定元素的值。
+
{{jsxref("Atomics.notify()")}}
+
唤醒等待队列中正在数组指定位置的元素上等待的线程。返回值为成功唤醒的线程数量。
+
{{jsxref("Atomics.or()")}}
+
将指定位置上的数组元素与给定的值相或,并返回或操作前该元素的值。
+
{{jsxref("Atomics.store()")}}
+
将数组中指定的元素设置为给定的值,并返回该值
+
{{jsxref("Atomics.sub()")}}
+
将指定位置上的数组元素与给定的值相减,并返回相减前该元素的值。
+
{{jsxref("Atomics.wait()")}}
+
检测数组中某个指定位置上的值是否仍然是给定值,是则保持挂起直到被唤醒或超时。返回值为 "ok"、"not-equal" 或 "time-out"。调用时,如果当前线程不允许阻塞,则会抛出异常(大多数浏览器都不允许在主线程中调用 wait())。
+
{{jsxref("Atomics.xor()")}}
+
将指定位置上的数组元素与给定的值相异或,并返回异或操作前该元素的值。
+
+ +

示例

+ +

使用 Atomics

+ +
const sab = new SharedArrayBuffer(1024);
+const ta = new Uint8Array(sab);
+
+ta[0];
+// 0
+
+ta[0] = 5;
+// 5
+
+Atomics.add(ta, 0, 12);
+// 5
+Atomics.load(ta, 0);
+// 17 ✅
+// 12 ❌
+
+Atomics.and(ta, 0, 1);
+// 17
+Atomics.load(ta, 0);
+// 1
+
+Atomics.compareExchange(ta, 0, 5, 12);
+Atomics.load(ta, 0); // 12
+
+Atomics.exchange(ta, 0, 12);
+Atomics.load(ta, 0); // 12
+
+Atomics.isLockFree(1); // true
+Atomics.isLockFree(2); // true
+Atomics.isLockFree(3); // false
+Atomics.isLockFree(4); // true
+
+Atomics.or(ta, 0, 1);
+Atomics.load(ta, 0);  // 5
+
+Atomics.store(ta, 0, 12); // 12
+
+Atomics.sub(ta, 0, 2);
+Atomics.load(ta, 0); // 3
+
+Atomics.xor(ta, 0, 1);
+Atomics.load(ta, 0); // 4
+
+ +

Waiting 和 notifiying

+ +

给定一个共享的 Int32Array

+ +
const sab = new SharedArrayBuffer(1024);
+const int32 = new Int32Array(sab);
+
+ +

读取线程正在休眠并位置0上等待。只要该位置应为0,它就不会继续。但是,一旦写入线程存储了新值,写入线程将通知它并返回新值(123)。

+ +
Atomics.wait(int32, 0, 0);
+console.log(int32[0]); // 123
+
+ +

写入线程存储一个新值并再写入完成时通知等待线程:

+ +
console.log(int32[0]); // 0;
+Atomics.store(int32, 0, 123);
+Atomics.notify(int32, 0, 1);
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-atomics-object', 'Atomics')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Atomics")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/islockfree/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/islockfree/index.html new file mode 100644 index 0000000000..be8b32b587 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/islockfree/index.html @@ -0,0 +1,69 @@ +--- +title: Atomics.isLockFree() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/isLockFree +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/isLockFree +--- +
{{JSRef}} {{SeeCompatTable}}
+ +

静态方法 Atomics.isLockFree() 用于校验是否能够使用原子操作的TypedArray的标准字节长度之一. 若该字节长度为可处理的TypedArray标准字节长度之一则返回  true.  TypedArray的标准字节长度参见 BYTES_PER_ELEMENT

+ +
{{EmbedInteractiveExample("pages/js/atomics-islockfree.html")}}
+ + + +

语法

+ +
Atomics.isLockFree(size)
+
+ +

参数

+ +
+
size
+
整形.字节长度,通常为TypedArray.BYTES_PER_ELEMENT
+
+ +

返回值

+ +

 {{jsxref("Boolean")}} 是否为能够使用原子操作的TypedArray的标准字节长度之一.

+ +

示例

+ +
Atomics.isLockFree(1); // true
+Atomics.isLockFree(2); // true
+Atomics.isLockFree(3); // false
+Atomics.isLockFree(4); // true
+Atomics.isLockFree(5); // false
+Atomics.isLockFree(6); // false
+Atomics.isLockFree(7); // false
+Atomics.isLockFree(8); // false
+Atomics.isLockFree(Float64Array.BYTES_PER_ELEMENT); // false,Atomics方法无法处理Float64Array
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Shared Memory', '#Atomics.isLockFree', 'Atomics.isLockFree')}}{{Spec2('Shared Memory')}}Initial definition.
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Atomics.isLockFree")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/load/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/load/index.html new file mode 100644 index 0000000000..2129a3a4ab --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/load/index.html @@ -0,0 +1,76 @@ +--- +title: Atomics.load() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/load +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/load +--- +
{{JSRef}}
+ +

静态方法 Atomics.load() 返回一个数组当中给定位置的值。

+ +
{{EmbedInteractiveExample("pages/js/atomics-load.html")}}
+ + + +

语法

+ +
Atomics.load(typedArray, index)
+
+ +

参数

+ +
+
typedArray
+
一个共享的整型数组。可以是 {{jsxref("Int8Array")}},{{jsxref("Uint8Array")}},{{jsxref("Int16Array")}},{{jsxref("Uint16Array")}},{{jsxref("Int32Array")}} 或 {{jsxref("Uint32Array")}}.
+
index
+
在 typedArray 中需要加载的位置
+
+ +

返回值

+ +

给定位置的值 (typedArray[index])。

+ +

异常

+ + + +

示例

+ +
var sab = new SharedArrayBuffer(1024);
+var ta = new Uint8Array(sab);
+
+Atomics.add(ta, 0, 12);
+Atomics.load(ta, 0); // 12
+ +

规范

+ + + + + + + + + + + + + + +
规范状态论述
{{SpecName('ESDraft', '#sec-atomics.load', 'Atomics.load')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Atomics.load")}}

+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/notify/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/notify/index.html new file mode 100644 index 0000000000..bf2399192c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/notify/index.html @@ -0,0 +1,93 @@ +--- +title: Atomics.notify() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/notify +tags: + - Atomics + - JavaScript + - Method + - Shared Memory +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/notify +--- +
{{JSRef}}
+ +

静态方法 Atomics.notify() 提醒一些在等待队列中休眠的代理。

+ +
+

注意:本操作仅在共享的 {{jsxref("Int32Array")}} 下可用。

+
+ +

语法

+ +
Atomics.notify(typedArray, index, count)
+
+ +

参数

+ +
+
typedArray
+
一个共享的 {{jsxref("Int32Array")}}。
+
index
+
typedArray 中要唤醒的目标索引。
+
count
+
要通知的正在休眠的代理的数量。默认是 {{jsxref("Infinity", "+Infinity")}}。
+
+ +

返回值

+ +

被唤醒的代理的数量。

+ +

异常

+ + + +

示例

+ +

分配一个共享的 Int32Array

+ +
var sab = new SharedArrayBuffer(1024);
+var int32 = new Int32Array(sab);
+
+ +

一个读线程会进入休眠并监视索引0处的值(默认为0)。只要索引0处的值不为0,读进程就会唤醒。但是,一旦写进程存储了一个新的值,写进程就会产生一个提醒并返回写入后的新值(123)。(这里示例有问题或者说对初学者不友好,如果直接在浏览器控制台运行下面代码会报错,因为我们不能尝试睡眠主线程,可以见 重学js —— 结构化数据之Atomics对象,同时我在 codepen 写了一个示例:Atomics.wait使用示例

+ +
Atomics.wait(int32, 0, 0);
+console.log(int32[0]); // 123
+ +

写进程写入一个新值并告知等待进程已经写入成功了:

+ +
console.log(int32[0]); // 0;
+Atomics.store(int32, 0, 123);
+Atomics.notify(int32, 0, 1);
+ +

规范

+ + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ESDraft', '#sec-atomics.notify', 'Atomics.notify')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Atomics.notify")}}

+ +

相关文档

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/or/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/or/index.html new file mode 100644 index 0000000000..286e89cc0a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/or/index.html @@ -0,0 +1,129 @@ +--- +title: Atomics.or() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/or +tags: + - Atomics + - JavaScript + - Method + - Shared Memory +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/or +--- +
{{JSRef}}
+ +

静态方法 Atomics.or() 用数组中指定位置的值进行一次按位或运算,并返回未计算时数组中指定位置处的值。这个atomic操作保证了在修改后的值被写回之前没有其它的写入操作发生。

+ +
{{EmbedInteractiveExample("pages/js/atomics-or.html")}}
+ + + +

Syntax

+ +
Atomics.or(typedArray, index, value)
+
+ +

参数

+ +
+
typedArray
+
一个共享的int数组,类型为 {{jsxref("Int8Array")}}、{{jsxref("Uint8Array")}}、{{jsxref("Int16Array")}}、{{jsxref("Uint16Array")}}、{{jsxref("Int32Array")}} 或 {{jsxref("Uint32Array")}}。
+
index
+
typedArray 中要进行按位或运算的索引。
+
value
+
要进行按位或运算的数。
+
+ +

返回值

+ +

typedArray[index] 处运算前的值。

+ +

异常

+ + + +

详情

+ +

当 a 或者 b 为1时,按位或运算结果为1。或运算真值表如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba | b
000
011
101
111
+ +

例如,让 5 & 1 进行按位或运算的结果是 0101 ,也就是十进制的5:

+ +
5  0101
+1  0001
+   ----
+5  0101
+
+ +

示例

+ +
var sab = new SharedArrayBuffer(1024);
+var ta = new Uint8Array(sab);
+ta[0] = 2;
+
+Atomics.or(ta, 0, 1); // returns 2, the old value
+Atomics.load(ta, 0);  // 3
+ +

规范

+ + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ESDraft', '#sec-atomics.or', 'Atomics.or')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Atomics.or")}}

+ +

相关文档

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/store/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/store/index.html new file mode 100644 index 0000000000..bfc5a03982 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/store/index.html @@ -0,0 +1,77 @@ +--- +title: Atomics.store() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/store +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/store +--- +
{{JSRef}}
+ +

静态的Atomics.store()方法将给定的值存储在数组中的指定位置,并返回该值。.

+ +
{{EmbedInteractiveExample("pages/js/atomics-store.html")}}
+ + + +

语法

+ +
Atomics.store(typedArray, index, value)
+
+ +

参数

+ +
+
typedArray
+
一个指定类型的shared数组. 类型为 {{jsxref("Int8Array")}}, {{jsxref("Uint8Array")}}, {{jsxref("Int16Array")}}, {{jsxref("Uint16Array")}}, {{jsxref("Int32Array")}}, 或者 {{jsxref("Uint32Array")}}其中一个.
+
index
+
typedArray中用来存储value的位置.
+
value
+
要存储的数字.
+
+ +

返回值

+ +

被存储的值.

+ +

异常

+ + + +

示例

+ +
var sab = new SharedArrayBuffer(1024);
+var ta = new Uint8Array(sab);
+
+Atomics.store(ta, 0, 12); // 12
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-atomics.store', 'Atomics.store')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Atomics.store")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/sub/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/sub/index.html new file mode 100644 index 0000000000..c5a43d3e35 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/sub/index.html @@ -0,0 +1,82 @@ +--- +title: Atomics.sub() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/sub +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/sub +--- +
{{JSRef}}
+ +
Atomics.sub() 静态方法在数组中的给定位置减去给定值,并返回该位置的旧值。这个原子操作保证在修改后的值被写回之前不会发生其他写操作。
+ +
+ +
{{EmbedInteractiveExample("pages/js/atomics-sub.html")}}
+ + + +

语法

+ +
Atomics.sub(typedArray, index, value)
+
+ +

参数

+ +
+
typedArray
+
一个共享的整型 typed array。 例如 {{jsxref("Int8Array")}}, {{jsxref("Uint8Array")}}, {{jsxref("Int16Array")}}, {{jsxref("Uint16Array")}}, {{jsxref("Int32Array")}}, 或者 {{jsxref("Uint32Array")}}.
+
index
+
要被 value 值减去的 typedArray 索引位置。
+
value
+
要减去的数字。
+
+ +

返回值

+ +

给定位置的旧值 (typedArray[index])。

+ +

异常

+ + + +

例子

+ +
const sab = new SharedArrayBuffer(1024);
+const ta = new Uint8Array(sab);
+ta[0] = 48;
+
+Atomics.sub(ta, 0, 12); // returns 48, the old value
+Atomics.load(ta, 0); // 36
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-atomics.sub', 'Atomics.sub')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.Atomics.sub")}}

+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/wait/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/wait/index.html new file mode 100644 index 0000000000..6a14b9260a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/wait/index.html @@ -0,0 +1,95 @@ +--- +title: Atomics.wait() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/wait +tags: + - Atomics + - JavaScript + - Method + - Shared Memory +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/wait +--- +
{{JSRef}}
+ +

静态方法 Atomics.wait() 确保了一个在 {{jsxref("Int32Array")}} 数组中给定位置的值没有发生变化、仍然是给定的值时进程将会睡眠,直到被唤醒或超时。该方法返回一个字符串,值为"ok", "not-equal", 或 "timed-out" 之一。

+ +
+

注意: 这项操作仅允许同一个共享内存的 {{jsxref("Int32Array")}} 配合使用并且无法运行在主线程中。

+
+ +

语法

+ +
Atomics.wait(typedArray, index, value[, timeout])
+
+ +

参数

+ +
+
typedArray
+
一个共享内存的  {{jsxref("Int32Array")}} 数组。
+
index
+
给定需要检测的 typedArray 数组的位置索引。
+
value
+
给定需要检测的位置索引的预期值。
+
timeout {{optional_inline}}
+
超时前等待的毫秒数。 {{jsxref("Infinity")}}, 如未提供该参数,将为无穷大。
+
+ +

返回值

+ +

一个 {{jsxref("String")}} 字符串,值为 "ok", "not-equal", 或 "timed-out" 三种之一。

+ +

异常

+ + + +

示例

+ +

创建一个共享内存的 Int32Array :

+ +
var sab = new SharedArrayBuffer(1024);
+var int32 = new Int32Array(sab);
+
+ +

检测给定的数组索引0的值,如果它如预期一般的等于我们给定的值0,则这个读取线程将会睡眠等待。一旦当有一个写入线程在这个位置存储了一个新值,它将会收到写入线程的通知并且返回新值 (123) :

+ +
Atomics.wait(int32, 0, 0);
+console.log(int32[0]); // 123
+ +

一旦某个写入线程存储了一个新值到int32 的索引0位置,则通知给该等待线程:

+ +
console.log(int32[0]); // 0;
+Atomics.store(int32, 0, 123);
+Atomics.notify(int32, 0, 1);
+ +

规范

+ + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-atomics.wait', 'Atomics.wait')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.Atomics.wait")}}

+ +

相关参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/atomics/xor/index.html b/files/zh-cn/web/javascript/reference/global_objects/atomics/xor/index.html new file mode 100644 index 0000000000..83b0bdfb46 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/atomics/xor/index.html @@ -0,0 +1,126 @@ +--- +title: Atomics.xor() +slug: Web/JavaScript/Reference/Global_Objects/Atomics/xor +translation_of: Web/JavaScript/Reference/Global_Objects/Atomics/xor +--- +
{{JSRef}}
+ +
Atomics.xor() 静态方法会在数组中给定位置进行一次按位异或操作,并返回该位置的旧值。这个原子操作保证在修改后的值被写回之前不会发生其他写操作。
+ +
+ +
{{EmbedInteractiveExample("pages/js/atomics-xor.html")}}
+ + + +

语法

+ +
Atomics.xor(typedArray, index, value)
+
+ +

参数

+ +
+
typedArray
+
一个共享的整型 typed array。例如 {{jsxref("Int8Array")}}, {{jsxref("Uint8Array")}}, {{jsxref("Int16Array")}}, {{jsxref("Uint16Array")}}, {{jsxref("Int32Array")}}, 或者 {{jsxref("Uint32Array")}}.
+
index
+
typedArray 中需要进行按位异或的索引位置。
+
value
+
要进行按位异或的数字。
+
+ +

返回值

+ +

给定位置的旧值 (typedArray[index])。

+ +

异常

+ + + +

描述

+ +

如果a和b不同,则按位异或操作产生1。异或操作的真值表如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba ^ b
000
011
101
110
+ +

例如,按位异或 5 & 1 将返回 0100,而 0100 是十进制为 4 。

+ +
5  0101
+1  0001
+   ----
+4  0100
+
+ +

例子

+ +
const sab = new SharedArrayBuffer(1024);
+const ta = new Uint8Array(sab);
+ta[0] = 5;
+
+Atomics.xor(ta, 0, 1); // returns 5, the old value
+Atomics.load(ta, 0);  // 4
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-atomics.xor', 'Atomics.xor')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.Atomics.xor")}}

+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/bigint/asintn/index.html b/files/zh-cn/web/javascript/reference/global_objects/bigint/asintn/index.html new file mode 100644 index 0000000000..cab753a464 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/bigint/asintn/index.html @@ -0,0 +1,73 @@ +--- +title: BigInt.asIntN() +slug: Web/JavaScript/Reference/Global_Objects/BigInt/asIntN +translation_of: Web/JavaScript/Reference/Global_Objects/BigInt/asIntN +--- +
{{JSRef}}
+ +

BigInt.asIntN 静态方法将 BigInt 值转换为一个 -2width-1 与 2width-1-1 之间的有符号整数。

+ +
{{EmbedInteractiveExample("pages/js/bigint-asintn.html")}}
+ + + +

语法

+ +
BigInt.asIntN(width, bigint);
+ +

参数

+ +
+
width
+
可存储整数的位数。
+
bigint
+
要存储在指定位数上的整数。
+
+ +

返回值

+ +

bigint 模(modulo) 2width 作为有符号整数的值。

+ +

例子

+ +

保持在64位范围内

+ +

BigInt.asIntN() 方法对于保持在64位(64-bit)算数范围内非常有用。

+ +
const max = 2n ** (64n - 1n) - 1n;
+
+BigInt.asIntN(64, max);
+// ↪ 9223372036854775807n
+
+BigInt.asIntN(64, max + 1n);
+// ↪ -9223372036854775808n
+// negative because of overflow
+
+ +

标准

+ + + + + + + + + + + + +
SpecificationStatus
{{SpecName('ESDraft', '#sec-bigint.asintn', 'BigInt.asIntN()')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.BigInt.asIntN")}}

+ +

请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/bigint/asuintn/index.html b/files/zh-cn/web/javascript/reference/global_objects/bigint/asuintn/index.html new file mode 100644 index 0000000000..2c813a51ad --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/bigint/asuintn/index.html @@ -0,0 +1,72 @@ +--- +title: BigInt.asUintN() +slug: Web/JavaScript/Reference/Global_Objects/BigInt/asUintN +translation_of: Web/JavaScript/Reference/Global_Objects/BigInt/asUintN +--- +
{{JSRef}}
+ +

BigInt.asUintN 静态方法将 BigInt 转换为一个 0 和 2width-1 之间的无符号整数。

+ +
{{EmbedInteractiveExample("pages/js/bigint-asuintn.html")}}
+ + + +

语法

+ +
BigInt.asUintN(width, bigint);
+ +

参数

+ +
+
width
+
可存储整数的位数。
+
bigint
+
 要存储在指定位数上的整数。
+
+ +

返回值

+ +

bigint 模(modulo) 2width 作为无符号整数的值。

+ +

例子

+ +

保持在64位范围内

+ +

BigInt.asUintN() 方法对于保持在64位(64-bit)算数范围内非常有用。

+ +
const max = 2n ** 64n - 1n;
+
+BigInt.asUintN(64, max);
+// ↪ 18446744073709551615n
+
+BigInt.asUintN(64, max + 1n);
+// ↪ 0n
+// zero because of overflow
+ +

标准

+ + + + + + + + + + + + +
SpecificationStatus
{{SpecName('ESDraft', '#sec-bigint.asuintn', 'BigInt.asUintN()')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.BigInt.asUintN")}}

+ +

请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/bigint/bigint/index.html b/files/zh-cn/web/javascript/reference/global_objects/bigint/bigint/index.html new file mode 100644 index 0000000000..7e7a2923f6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/bigint/bigint/index.html @@ -0,0 +1,57 @@ +--- +title: BigInt() constructor +slug: Web/JavaScript/Reference/Global_Objects/BigInt/BigInt +translation_of: Web/JavaScript/Reference/Global_Objects/BigInt/BigInt +--- +
{{JSRef}}
+ +

 BigInt() 构造函数用来创建 {{jsxref("BigInt")}} 对象。

+ +

语法

+ +
BigInt(value);
+
+ +

参数

+ +
+
value
+
被创建的对象的数值。 可以是字符串或整数。
+
+ +
+

Note: BigInt() 不与 {{JSxRef("Operators/new", "new")}} 运算符一起使用。

+
+ +

例子

+ +
BigInt(123);
+// 123n
+
+ +

规范

+ + + + + + + + + + + + +
SpecificationStatus
{{SpecName('ESDraft', '#sec-bigint-constructor', 'BigInt constructor')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.BigInt.BigInt")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/bigint/index.html b/files/zh-cn/web/javascript/reference/global_objects/bigint/index.html new file mode 100644 index 0000000000..205b9f9952 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/bigint/index.html @@ -0,0 +1,272 @@ +--- +title: BigInt +slug: Web/JavaScript/Reference/Global_Objects/BigInt +translation_of: Web/JavaScript/Reference/Global_Objects/BigInt +--- +

{{JSRef}}

+ +

BigInt 是一种内置对象,它提供了一种方法来表示大于 253 - 1 的整数。这原本是 Javascript中可以用 {{JSxRef("Number")}} 表示的最大数字。BigInt 可以表示任意大的整数。

+ +
+
+ +

描述

+ +

可以用在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n,或者调用函数BigInt()

+ +
const theBiggestInt = 9007199254740991n;
+
+const alsoHuge = BigInt(9007199254740991);
+// ↪ 9007199254740991n
+
+const hugeString = BigInt("9007199254740991");
+// ↪ 9007199254740991n
+
+const hugeHex = BigInt("0x1fffffffffffff");
+// ↪ 9007199254740991n
+
+const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111");
+// ↪ 9007199254740991n
+ +

它在某些方面类似于 {{jsxref("Global_Objects/Number", "Number")}} ,但是也有几个关键的不同点:不能用于 {{jsxref("Global_Objects/Math", "Math")}} 对象中的方法;不能和任何 {{jsxref("Global_Objects/Number", "Number")}} 实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt 变量在转换成 {{jsxref("Global_Objects/Number", "Number")}} 变量时可能会丢失精度。

+ +

类型信息

+ +

使用 typeof 测试时, BigInt 对象返回 "bigint" :

+ +
typeof 1n === 'bigint'; // true
+typeof BigInt('1') === 'bigint'; // true
+ +

使用 Object 包装后, BigInt 被认为是一个普通 "object" :

+ +
typeof Object(1n) === 'object'; // true
+ +

运算

+ +

以下操作符可以和 BigInt 一起使用: +、`*`、`-`、`**`、`%` 。除 >>> (无符号右移)之外的 位操作 也可以支持。因为 BigInt 都是有符号的, >>> (无符号右移)不能用于 BigInt为了兼容 asm.js BigInt 不支持单目 (+) 运算符。

+ +
const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);
+// ↪ 9007199254740991n
+
+const maxPlusOne = previousMaxSafe + 1n;
+// ↪ 9007199254740992n
+
+const theFuture = previousMaxSafe + 2n;
+// ↪ 9007199254740993n, this works now!
+
+const multi = previousMaxSafe * 2n;
+// ↪ 18014398509481982n
+
+const subtr = multi – 10n;
+// ↪ 18014398509481972n
+
+const mod = multi % 10n;
+// ↪ 2n
+
+const bigN = 2n ** 54n;
+// ↪ 18014398509481984n
+
+bigN * -1n
+// ↪ –18014398509481984n
+
+ +

/ 操作符对于整数的运算也没问题。可是因为这些变量是 BigInt 而不是 BigDecimal ,该操作符结果会向零取整,也就是说不会返回小数部分。

+ +
+

当使用 BigInt 时,带小数的运算会被取整。

+
+ +
const expected = 4n / 2n;
+// ↪ 2n
+
+const rounded = 5n / 2n;
+// ↪ 2n, not 2.5n
+
+
+ +

比较

+ +

BigInt 和 {{jsxref("Global_Objects/Number", "Number")}} 不是严格相等的,但是宽松相等的。

+ +
0n === 0
+// ↪ false
+
+0n == 0
+// ↪ true
+ +

{{jsxref("Global_Objects/Number", "Number")}} 和 BigInt 可以进行比较。

+ +
1n < 2
+// ↪ true
+
+2n > 1
+// ↪ true
+
+2 > 2
+// ↪ false
+
+2n > 2
+// ↪ false
+
+2n >= 2
+// ↪ true
+ +

两者也可以混在一个数组内并排序。

+ +
const mixed = [4n, 6, -12n, 10, 4, 0, 0n];
+// ↪  [4n, 6, -12n, 10, 4, 0, 0n]
+
+mixed.sort();
+// ↪ [-12n, 0, 0n, 10, 4n, 4, 6]
+ +

注意被  Object 包装的 BigInts 使用 object 的比较规则进行比较,只用同一个对象在比较时才会相等。

+ +
0n === Object(0n); // false
+Object(0n) === Object(0n); // false
+
+const o = Object(0n);
+o === o // true
+ +

条件

+ +

BigInt 在需要转换成 {{jsxref("Global_Objects/Boolean", "Boolean")}} 的时表现跟 {{jsxref("Global_Objects/Number", "Number")}} 类似:如通过 {{jsxref("Global_Objects/Boolean", "Boolean")}} 函数转换;用于 {{jsxref("Operators/Logical_Operators", "Logical Operators")}}  ||, `&&`, 和 ! 的操作数;或者用于在像 {{jsxref("Statements/if...else", "if statement")}} 这样的条件语句中。

+ +
if (0n) {
+  console.log('Hello from the if!');
+} else {
+  console.log('Hello from the else!');
+}
+
+// ↪ "Hello from the else!"
+
+0n || 12n
+// ↪ 12n
+
+0n && 12n
+// ↪ 0n
+
+Boolean(0n)
+// ↪ false
+
+Boolean(12n)
+// ↪ true
+
+!12n
+// ↪ false
+
+!0n
+// ↪ true
+
+ +

构造器

+ +
+
BigInt()
+
创建{{jsxref("BigInt")}} 对象。
+
+ +

静态方法

+ +
+
{{JSxRef("BigInt.asIntN()")}}
+
将 BigInt 值转换为一个 -2width-1 与 2width-1-1 之间的有符号整数。
+
{{JSxRef("BigInt.asUintN()")}}
+
将一个 BigInt 值转换为 0 与 2width-1 之间的无符号整数。
+
+ +

实例方法

+ +
+
{{JSxRef("BigInt.prototype.toLocaleString()")}}
+
返回此数字的 language-sensitive 形式的字符串。覆盖 {{JSxRef("Object.prototype.toLocaleString()")}}  方法。
+
{{JSxRef("BigInt.prototype.toString()")}}
+
返回以指定基数(base)表示指定数字的字符串。覆盖 {{JSxRef("Object.prototype.toString()")}} 方法。
+
{{JSxRef("BigInt.prototype.valueOf()")}}
+
返回指定对象的基元值。 覆盖 {{JSxRef("Object.prototype.valueOf()")}} 方法。
+
+ +

使用建议

+ +

转化

+ +

由于在 {{JSxRef("Number")}} 与 BigInt 之间进行转换会损失精度,因而建议仅在值可能大于253 时使用 BigInt 类型,并且不在两种类型之间进行相互转换。

+ +

密码学

+ +

由于对 BigInt 的操作不是常数时间的,因而 BigInt 不适合用于密码学

+ +

在 JSON 中使用

+ +

对任何 BigInt 值使用 {{jsxref("JSON.stringify()")}} 都会引发 TypeError,因为默认情况下 BigInt 值不会在 JSON 中序列化。但是,如果需要,可以实现 toJSON 方法:

+ +
BigInt.prototype.toJSON = function() { return this.toString(); }
+ +

JSON.stringify 现在生成如下字符串,而不是抛出异常:

+ +
JSON.stringify(BigInt(1));
+// '"1"'
+ +

例子

+ +

Calculating Primes

+ +
function isPrime(p) {
+  for (let i = 2n; i * i <= p; i++) {
+    if (p % i === 0n) return false;
+  }
+  return true;
+}
+
+// Takes a BigInt as an argument and returns a BigInt
+function nthPrime(nth) {
+  let maybePrime = 2n;
+  let prime = 0n;
+
+  while (nth >= 0n) {
+    if (isPrime(maybePrime)) {
+      nth -= 1n;
+      prime = maybePrime;
+    }
+    maybePrime += 1n;
+  }
+
+  return prime;
+}
+
+nthPrime(20n)
+// ↪ 73n
+ +

标准

+ + + + + + + + + + + + +
标准状态
BigInt第4阶段
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.BigInt")}}

+ +

实施进度

+ +

下表提供了此功能的每日实现状态,因为此功能尚未达到跨浏览器稳定性。数据是通过在 Test262 中运行相关的特性测试生成的,Test262 是 JavaScript 的标准测试套件,在夜间构建,或者是每个浏览器的 JavaScript 引擎的最新版本中运行。

+ +

{{EmbedTest262ReportResultsTable("BigInt")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/bigint/tolocalestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/bigint/tolocalestring/index.html new file mode 100644 index 0000000000..434bceb0d9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/bigint/tolocalestring/index.html @@ -0,0 +1,116 @@ +--- +title: BigInt.prototype.toLocaleString() +slug: Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString +translation_of: Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString +--- +
{{JSRef}}
+ +

toLocaleString() 方法返回一个字符串,该字符串具有此 BigInt 的 language-sensitive 表达形式。

+ +
{{EmbedInteractiveExample("pages/js/bigint-tolocalestring.html")}}
+ + + +

语法

+ +
bigIntObj.toLocaleString([locales [, options]])
+ +

参数

+ +

locales 和 options 参数可自定义函数的行为,并允许应用程序指定应使用其格式约定的语言。在忽略 locales 和 options 参数的实现中,使用的 locale 和返回的字符串形式完全依赖于实现。

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat', '参数')}}
+ +

返回值

+ +

具有此 BigInt 的 language-sensitive 表示形式的字符串。

+ +

例子

+ +

Using toLocaleString

+ +

在不指定语言环境的基本用法中,将返回默认语言环境中带默认选项的格式化字符串。

+ +
var bigint = 3500n;
+
+bigint.toLocaleString();
+// Displays "3,500" if in U.S. English locale
+
+ +

Using locales

+ +

这个例子展示了本地化数字格式的一些变体。为了获得应用程序用户界面中使用的语言的格式,请确保使用 locales 参数指定该语言(可能还有一些备用语言):

+ +
var bigint = 123456789123456789n;
+
+// German uses period for thousands
+console.log(bigint.toLocaleString('de-DE'));
+// → 123.456.789.123.456.789
+
+// Arabic in most Arabic speaking countries uses Eastern Arabic digits
+console.log(bigint.toLocaleString('ar-EG'));
+// → ١٢٣٬٤٥٦٬٧٨٩٬١٢٣٬٤٥٦٬٧٨٩
+
+// India uses thousands/lakh/crore separators
+console.log(bigint.toLocaleString('en-IN'));
+// → 1,23,45,67,89,12,34,56,789
+
+// the nu extension key requests a numbering system, e.g. Chinese decimal
+console.log(bigint.toLocaleString('zh-Hans-CN-u-nu-hanidec'));
+// → 一二三,四五六,七八九,一二三,四五六,七八九
+
+// when requesting a language that may not be supported, such as
+// Balinese, include a fallback language, in this case Indonesian
+console.log(bigint.toLocaleString(['ban', 'id']));
+// → 123.456.789.123.456.789
+
+ +

Using options

+ +

toLocaleString 提供的结果可以使用 options 参数进行自定义:

+ +
var bigint = 123456789123456789n;
+
+// request a currency format
+console.log(bigint.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
+// → 123.456.789.123.456.789,00 €
+
+// the Japanese yen doesn't use a minor unit
+console.log(bigint.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
+// → ¥123,456,789,123,456,789
+
+// limit to three significant digits
+console.log(bigint.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
+// → 1,23,00,00,00,00,00,00,000
+
+ +

性能

+ +

格式化大量数字时,最好创建 {{jsxref("NumberFormat")}} 对象并使用其 {{jsxref("NumberFormat.format")}} 属性提供的函数。

+ +

标准

+ + + + + + + + + + + + +
SpecificationStatus
BigIntStage 3
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.BigInt.toLocaleString")}}

+ +

请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/bigint/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/bigint/tostring/index.html new file mode 100644 index 0000000000..487fe80ad2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/bigint/tostring/index.html @@ -0,0 +1,91 @@ +--- +title: BigInt.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/BigInt/toString +translation_of: Web/JavaScript/Reference/Global_Objects/BigInt/toString +--- +
{{JSRef}}
+ +

toString() 方法返回一个字符串,表示指定 {{jsxref("BigInt")}} 对象。 后面的 "n" 不是字符串的一部分。

+ +
{{EmbedInteractiveExample("pages/js/bigint-tostring.html")}}
+ + + +

语法

+ +
bigIntObj.toString([radix])
+ +

参数

+ +
+
radix{{Optional_inline}}
+
可选,介于 2 到 36 之间的整数,指定用于表示数值的基数。
+
+ +

返回值

+ +

表示指定 {{jsxref("BigInt")}} 对象的字符串。

+ +

异常

+ +
+
{{jsxref("RangeError")}}
+
如果 toString() 的基数小于 2 或大于 36, 则抛出 {{jsxref("RangeError")}}。
+
+ +

描述

+ +

{{jsxref("BigInt")}} 对象重写 {{jsxref("Object")}} 对象的 toString() 方法;它不继承 {{jsxref("Object.prototype.toString()")}}。对于 {{jsxref( "BigInt")}} 对象,toString() 方法返回指定基数中对象的字符串表示形式。

+ +

toString() 方法解析其第一个参数,并尝试返回指定基数(base)的字符串表示形式。对于大于 10 的参数,使用字母表中的字母表示大于 9 的数字。例如,对于十六进制数(以16为基数),使用 a 到 f。

+ +

如果未指定基数,则假定首选基数为10。

+ +

如果 bigIntObj 为负,则保留符号。即使基数是 2,情况也是如此;返回的字符串是 bigIntObj 的正二进制表示,前面是一个 - 符号,而不是 bigIntObj 的两个补码。

+ +

例子

+ +

Using toString

+ +
17n.toString();      // '17'
+66n.toString(2);     // '1000010'
+254n.toString(16);   // 'fe'
+-10n.toString(2);    // -1010'
+-0xffn.toString(2);  // '-11111111'
+
+ +

Negative-zero BigInt

+ +

没有负零 BigInt,因为整数中没有负零。-0.0 是一个 IEEE 浮点概念,只出现在JavaScript {{jsxref("Number")}} 类型中。

+ +
(-0n).toString();      // '0'
+BigInt(-0).toString(); // '0'
+ +

标准

+ + + + + + + + + + + + +
SpecificationStatus
{{SpecName('ESDraft', '#sec-bigint.prototype.tostring', 'BigInt.prototype.toString()')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.BigInt.toString")}}

+ +

请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/bigint/valueof/index.html b/files/zh-cn/web/javascript/reference/global_objects/bigint/valueof/index.html new file mode 100644 index 0000000000..0487cfbef3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/bigint/valueof/index.html @@ -0,0 +1,55 @@ +--- +title: BigInt.prototype.valueOf() +slug: Web/JavaScript/Reference/Global_Objects/BigInt/valueOf +translation_of: Web/JavaScript/Reference/Global_Objects/BigInt/valueOf +--- +
{{JSRef}}
+ +

valueOf() 方法返回 {{jsxref("BigInt")}} 对象包装的原始值。

+ +
{{EmbedInteractiveExample("pages/js/bigint-valueof.html")}}
+ + + +

语法

+ +
bigIntObj.valueOf()
+ +

返回值

+ +

表示指定 {{jsxref("BigInt")}} 对象的原始 BigInt 值。

+ +

例子

+ +

Using valueOf

+ +
typeof Object(1n); // object
+typeof Object(1n).valueOf(); // bigint
+
+ +

标准

+ + + + + + + + + + + + +
SpecificationStatus
{{SpecName('ESDraft', '#sec-bigint.prototype.valueof', 'BigInt.prototype.valueOf()')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.BigInt.valueOf")}}

+ +

请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/bigint64array/index.html b/files/zh-cn/web/javascript/reference/global_objects/bigint64array/index.html new file mode 100644 index 0000000000..23a2a114b6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/bigint64array/index.html @@ -0,0 +1,173 @@ +--- +title: BigInt64Array +slug: Web/JavaScript/Reference/Global_Objects/BigInt64Array +translation_of: Web/JavaScript/Reference/Global_Objects/BigInt64Array +--- +
+

{{JSRef}}

+ +

BigInt64Array 类型的数组代表由64位有符号整数组成的数组。如果需要控制字节顺序的话,请使用 {{jsxref("DataView")}} 代替。内容初始化为 0n 。一旦建立,就可以使用对象的方法或使用标准数组索引语法(即使用中括号表示法)引用数组中的元素。

+
+ +

构造函数

+ +

BigInt64Array()

+ +

     添加一个新的BigInt64Array对象。

+ +

静态属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "BigInt64Array.BYTES_PER_ELEMENT")}}
+
+ +

   返回一个元素大小的数字值,BigInt64Array返回 8

+ +
+
{{jsxref("TypedArray.name", "BigInt64Array.name")}}
+
+ +

   返回构造函数名字的字符串值,如果是BigInt64Array 的话,就是"BigInt64Array".

+ +

实例属性

+ +
+
{{jsxref("TypedArray.prototype.buffer", "BigInt64Array.prototype.buffer")}}
+
返回被BigInt64Array引用的{{jsxref("ArrayBuffer")}} 。这在BigInt64Array对象构建时期就被锁定了,所以是只读的。
+
{{jsxref("TypedArray.prototype.byteLength", "BigInt64Array.prototype.byteLength")}}
+
返回BigInt64Array从{jsxref(“ArrayBuffer”)}}开始的长度(以字节为单位)。这在构造时已经被固定,因此是只读的。
+
{{jsxref("TypedArray.prototype.byteOffset", "BigInt64Array.prototype.byteOffset")}}
+
返回 BigInt64Array 从{jsxref(“ArrayBuffer”)}}开始的偏移量(以字节为单位)。这在构造时已被固定的,因此是只读。
+
{{jsxref("TypedArray.prototype.length", "BigInt64Array.prototype.length")}}
+
                 +

返回 BigInt64Array 中被 保留的元 素个数。这  在构造时是固定的,因此是只读   

+ +

 

+                  + +

  

+
+
+ +

实例方法

+ +
+
{{jsxref("TypedArray.copyWithin", "BigInt64Array.prototype.copyWithin()")}}
+
复制数组中的数组元素序列。另请参见{jsxref(“Array.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.entries", "BigInt64Array.prototype.entries()")}}
+
返回一个新的数组迭代器对象,该对象包含数组中每个索引的键/值对。另请参见{jsxref(“Array.prototype.entries()")}}.
+
{{jsxref("TypedArray.every", "BigInt64Array.prototype.every()")}}
+
测试数组中的所有元素是否通过函数提供的测试。另请参见{jsxref(“Array.prototype.every()")}}.
+
{{jsxref("TypedArray.fill", "BigInt64Array.prototype.fill()")}}
+
+
+
+
用静态值填充从起始索引到结束索引的数组的所有元素。另请参见{jsxref(“Array.prototype.fill()")}}
+
+
+
+
{{jsxref("TypedArray.filter", "BigInt64Array.prototype.filter()")}}
+
使用提供的筛选函数为其返回true的数组的所有元素创建一个新数组。另请参见{jsxref(“Array.prototype.filter()")}}
+
{{jsxref("TypedArray.find", "BigInt64Array.prototype.find()")}}
+
如果数组中的元素满足提供的测试函数,则返回数组中找到的值;如果未找到,则返回 undefined 。另请参见{jsxref(“Array.prototype.find()")}}.
+
{{jsxref("TypedArray.findIndex", "BigInt64Array.prototype.findIndex()")}}
+
如果数组中的元素满足提供的测试函数,则返回数组中找到的索引;如果未找到,则返回-1。另请参见{jsxref(“Array.prototype.findIndex()")}}.
+
{{jsxref("TypedArray.forEach", "BigInt64Array.prototype.forEach()")}}
+
为数组中的每个元素调用函数。另请参见{jsxref(“Array.prototype.forEach()")}}
+
{{jsxref("TypedArray.includes", "BigInt64Array.prototype.includes()")}}
+
确定类型化数组是否包含某个元素,并根据需要返回 truefalse 。另请参见{jsxref(“Array.prototype.includes()")}}.
+
{{jsxref("TypedArray.indexOf", "BigInt64Array.prototype.indexOf()")}}
+
返回数组中元素的第一个(最小)索引,等于指定值;如果找不到,则返回-1。另请参见{jsxref(“Array.prototype.indexOf()")}}
+
{{jsxref("TypedArray.join", "BigInt64Array.prototype.join()")}}
+
将数组的所有元素联接为字符串。另请参见{jsxref(“Array.prototype.join()")}}
+
{{jsxref("TypedArray.keys", "BigInt64Array.prototype.keys()")}}
+
返回一个新的 Array Iterator ,它包含数组中每个索引的键。另请参见{jsxref(“Array.prototype.keys()")}}.
+
{{jsxref("TypedArray.lastIndexOf", "BigInt64Array.prototype.lastIndexOf()")}}
+
返回数组中元素的最后一个(最大)索引,等于指定值;如果找不到,则返回-1。另请参见{jsxref(“Array.prototype.lastIndexOf()")}}.
+
{{jsxref("TypedArray.map", "BigInt64Array.prototype.map()")}}
+
创建一个新数组,其中包含对此数组中的每个元素调用所提供函数的结果。另请参见{jsxref(“Array.prototype.map()")}}.
+
{{jsxref("TypedArray.reduce", "BigInt64Array.prototype.reduce()")}}
+
对累加器和数组的每个值(从左到右)应用一个函数,以便将其减少为单个值。另请参见{jsxref(“Array.prototype.reduce()")}}.
+
{{jsxref("TypedArray.reduceRight", "BigInt64Array.prototype.reduceRight()")}}
+
对累加器和数组的每个值(从右到左)应用一个函数,以便将其减少为单个值。另请参见{jsxref(“Array.prototype.reduceRight()")}}.
+
{{jsxref("TypedArray.reverse", "BigInt64Array.prototype.reverse()")}}
+
反转数组元素的顺序-第一个变为最后一个,最后一个变为第一个。另请参见{jsxref(“Array.prototype.reverse()")}}.
+
{{jsxref("TypedArray.set", "BigInt64Array.prototype.set()")}}
+
在 typed array 中存储多个值,从指定数组读取输入值。
+
{{jsxref("TypedArray.slice", "BigInt64Array.prototype.slice()")}}
+
提取数组的一部分并返回一个新数组。另请参见{jsxref(“Array.prototype.slice()")}}.
+
{{jsxref("TypedArray.some", "BigInt64Array.prototype.some()")}}
+
如果此数组中至少有一个元素满足提供的测试函数,则返回true。另请参见{jsxref(“Array.prototype.some()")}}.
+
{{jsxref("TypedArray.sort", "BigInt64Array.prototype.sort()")}}
+
对数组的元素进行就地排序并返回数组。另请参见{jsxref(“Array.prototype.sort()")}}.
+
{{jsxref("TypedArray.subarray", "BigInt64Array.prototype.subarray()")}}
+
从给定的起始和结束元素索引返回一个新的 BigUint64Array
+
{{jsxref("TypedArray.values", "BigInt64Array.prototype.values()")}}
+
返回一个新的 Array Iterator 对象,该对象包含数组中每个索引的值。另请参见{jsxref(“Array.prototype.values()")}}.
+
{{jsxref("TypedArray.toLocaleString", "BigInt64Array.prototype.toLocaleString()")}}
+
返回表示数组及其元素的本地化字符串。另请参见{jsxref(“Array.prototype.toLocaleString()")}}.
+
{{jsxref("TypedArray.toString", "BigInt64Array.prototype.toString()")}}
+
返回表示数组及其元素的字符串。另请参见{jsxref(“Array.prototype.toString()")}}.
+
{{jsxref("TypedArray.@@iterator", "BigInt64Array.prototype[@@iterator]()")}}
+
返回一个新的 Array Iterator 对象,该对象包含数组中每个索引的值。
+
+ +

例子

+ +

不同的方法去创建一个 BigInt64Array

+ +
// From a length
+var bigint64 = new BigInt64Array(2);
+bigint64[0] = 42n;
+console.log(bigint64[0]); // 42n
+console.log(bigint64.length); // 2
+console.log(bigint64.BYTES_PER_ELEMENT); // 8
+
+// From an array
+var arr = new BigInt64Array([21n,31n]);
+console.log(arr[1]); // 31n
+
+// From another TypedArray
+var x = new BigInt64Array([21n, 31n]);
+var y = new BigInt64Array(x);
+console.log(y[0]); // 21n
+
+// From an ArrayBuffer
+var buffer = new ArrayBuffer(32);
+var z = new BigInt64Array(buffer, 0, 4);
+
+// From an iterable
+var iterable = function*(){ yield* [1n, 2n, 3n]; }();
+var bigint64 = new BigInt64Array(iterable);
+// BigInt64Array[1n, 2n, 3n]
+ +

规格

+ + + + + + + + + + + + +
Specification
+

{{SpecName("ESDraft", "#sec-typedarray-objects", "BigInt64Array")}}

+
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.BigInt64Array")}}

+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/biguint64array/index.html b/files/zh-cn/web/javascript/reference/global_objects/biguint64array/index.html new file mode 100644 index 0000000000..b689fe581e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/biguint64array/index.html @@ -0,0 +1,164 @@ +--- +title: BigUint64Array +slug: Web/JavaScript/Reference/Global_Objects/BigUint64Array +translation_of: Web/JavaScript/Reference/Global_Objects/BigUint64Array +--- +
 {{JSRef}}
+ +

BigUint64Array 类型数组表示一个平台字节顺序的64位无符号整型数组。如果想要控制字符顺序,请使用 {{jsxref("DataView")}} 替代。内容初始化为 0n. 创建之后可以使用对象中的方法或使用标准数组索引语法(括号表示法)来获取数组中的元素。

+ +

句法

+ +
new BigUint64Array();
+new BigUint64Array(length);
+new BigUint64Array(typedArray);
+new BigUint64Array(object);
+new BigUint64Array(buffer [, byteOffset [, length]]);
+ +

更多有关构造方法和参数的信息,参见 TypedArray.

+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "BigUint64Array.BYTES_PER_ELEMENT")}}
+
返回一个元素容量的数字值. 8 in the case of a BigUint64Array.
+
BigUint64Array.length
+
Static length property whose value is 3. For the actual length (number of elements), see {{jsxref("TypedArray.prototype.length", "BigUint64Array.prototype.length")}}.
+
{{jsxref("TypedArray.name", "BigUint64Array.name")}}
+
Returns the string value of the constructor name. In the case of the BigUint64Array type: "BigUint64Array".
+
{{jsxref("TypedArray.prototype", "BigUint64Array.prototype")}}
+
Prototype for the TypedArray objects.
+
+ +

Methods

+ +
+
{{jsxref("TypedArray.from", "BigUint64Array.from()")}}
+
Creates a new BigUint64Array from an array-like or iterable object. See also {{jsxref("Array.from()")}}.
+
{{jsxref("TypedArray.of", "BigUint64Array.of()")}}
+
Creates a new BigUint64Array with a variable number of arguments. See also {{jsxref("Array.of()")}}.
+
+ +

BigUint64Array prototype

+ +

All BigUint64Array objects inherit from {{jsxref("TypedArray.prototype", "%TypedArray%.prototype")}}.

+ +

Properties

+ +
+
BigUint64Array.prototype.constructor
+
Returns the function that created an instance's prototype. This is the BigUint64Array constructor by default.
+
{{jsxref("TypedArray.prototype.buffer", "BigUint64Array.prototype.buffer")}} {{readonlyInline}}
+
Returns the {{jsxref("ArrayBuffer")}} referenced by the BigUint64Array. Fixed at construction time and thus read only.
+
{{jsxref("TypedArray.prototype.byteLength", "BigUint64Array.prototype.byteLength")}} {{readonlyInline}}
+
Returns the length (in bytes) of the BigUint64Array from the start of its {{jsxref("ArrayBuffer")}}. Fixed at construction time and thus read only.
+
{{jsxref("TypedArray.prototype.byteOffset", "BigUint64Array.prototype.byteOffset")}} {{readonlyInline}}
+
Returns the offset (in bytes) of the BigUint64Array from the start of its {{jsxref("ArrayBuffer")}}. Fixed at construction time and thus read only.
+
{{jsxref("TypedArray.prototype.length", "BigUint64Array.prototype.length")}} {{readonlyInline}}
+
Returns the number of elements hold in the BigUint64Array. Fixed at construction time and thus read only.
+
+ +

Methods

+ +
+
{{jsxref("TypedArray.copyWithin", "BigUint64Array.prototype.copyWithin()")}}
+
Copies a sequence of array elements within the array. See also {{jsxref("Array.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.entries", "BigUint64Array.prototype.entries()")}}
+
Returns a new Array Iterator object that contains the key/value pairs for each index in the array. See also {{jsxref("Array.prototype.entries()")}}.
+
{{jsxref("TypedArray.every", "BigUint64Array.prototype.every()")}}
+
Tests whether all elements in the array pass the test provided by a function. See also {{jsxref("Array.prototype.every()")}}.
+
{{jsxref("TypedArray.fill", "BigUint64Array.prototype.fill()")}}
+
Fills all the elements of an array from a start index to an end index with a static value. See also {{jsxref("Array.prototype.fill()")}}.
+
{{jsxref("TypedArray.filter", "BigUint64Array.prototype.filter()")}}
+
Creates a new array with all of the elements of this array for which the provided filtering function returns true. See also {{jsxref("Array.prototype.filter()")}}.
+
{{jsxref("TypedArray.find", "BigUint64Array.prototype.find()")}}
+
Returns the found value in the array, if an element in the array satisfies the provided testing function or undefined if not found. See also {{jsxref("Array.prototype.find()")}}.
+
{{jsxref("TypedArray.findIndex", "BigUint64Array.prototype.findIndex()")}}
+
Returns the found index in the array, if an element in the array satisfies the provided testing function or -1 if not found. See also {{jsxref("Array.prototype.findIndex()")}}.
+
{{jsxref("TypedArray.forEach", "BigUint64Array.prototype.forEach()")}}
+
Calls a function for each element in the array. See also {{jsxref("Array.prototype.forEach()")}}.
+
{{jsxref("TypedArray.includes", "BigUint64Array.prototype.includes()")}}
+
Determines whether a typed array includes a certain element, returning true or false as appropriate. See also {{jsxref("Array.prototype.includes()")}}.
+
{{jsxref("TypedArray.indexOf", "BigUint64Array.prototype.indexOf()")}}
+
Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.indexOf()")}}.
+
{{jsxref("TypedArray.join", "BigUint64Array.prototype.join()")}}
+
Joins all elements of an array into a string. See also {{jsxref("Array.prototype.join()")}}.
+
{{jsxref("TypedArray.keys", "BigUint64Array.prototype.keys()")}}
+
Returns a new Array Iterator that contains the keys for each index in the array. See also {{jsxref("Array.prototype.keys()")}}.
+
{{jsxref("TypedArray.lastIndexOf", "BigUint64Array.prototype.lastIndexOf()")}}
+
Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.lastIndexOf()")}}.
+
{{jsxref("TypedArray.map", "BigUint64Array.prototype.map()")}}
+
Creates a new array with the results of calling a provided function on every element in this array. See also {{jsxref("Array.prototype.map()")}}.
+
{{jsxref("TypedArray.reduce", "BigUint64Array.prototype.reduce()")}}
+
Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. See also {{jsxref("Array.prototype.reduce()")}}.
+
{{jsxref("TypedArray.reduceRight", "BigUint64Array.prototype.reduceRight()")}}
+
Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. See also {{jsxref("Array.prototype.reduceRight()")}}.
+
{{jsxref("TypedArray.reverse", "BigUint64Array.prototype.reverse()")}}
+
Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first. See also {{jsxref("Array.prototype.reverse()")}}.
+
{{jsxref("TypedArray.set", "BigUint64Array.prototype.set()")}}
+
Stores multiple values in the typed array, reading input values from a specified array.
+
{{jsxref("TypedArray.slice", "BigUint64Array.prototype.slice()")}}
+
Extracts a section of an array and returns a new array. See also {{jsxref("Array.prototype.slice()")}}.
+
{{jsxref("TypedArray.some", "BigUint64Array.prototype.some()")}}
+
Returns true if at least one element in this array satisfies the provided testing function. See also {{jsxref("Array.prototype.some()")}}.
+
{{jsxref("TypedArray.sort", "BigUint64Array.prototype.sort()")}}
+
Sorts the elements of an array in place and returns the array. See also {{jsxref("Array.prototype.sort()")}}.
+
{{jsxref("TypedArray.subarray", "BigUint64Array.prototype.subarray()")}}
+
Returns a new BigUint64Array from the given start and end element index.
+
{{jsxref("TypedArray.values", "BigUint64Array.prototype.values()")}}
+
Returns a new Array Iterator object that contains the values for each index in the array. See also {{jsxref("Array.prototype.values()")}}.
+
{{jsxref("TypedArray.toLocaleString", "BigUint64Array.prototype.toLocaleString()")}}
+
Returns a localized string representing the array and its elements. See also {{jsxref("Array.prototype.toLocaleString()")}}.
+
{{jsxref("TypedArray.toString", "BigUint64Array.prototype.toString()")}}
+
Returns a string representing the array and its elements. See also {{jsxref("Array.prototype.toString()")}}.
+
{{jsxref("TypedArray.@@iterator", "BigUint64Array.prototype[@@iterator]()")}}
+
Returns a new Array Iterator object that contains the values for each index in the array.
+
+ +

Examples

+ +

Different ways to create a BigUint64Array:

+ +
// From a length
+var biguint64 = new BigUint64Array(2);
+biguint64[0] = 42n;
+console.log(biguint64[0]); // 42n
+console.log(biguint64.length); // 2
+console.log(biguint64.BYTES_PER_ELEMENT); // 8
+
+// From an array
+var arr = new BigUint64Array([21n,31n]);
+console.log(arr[1]); // 31n
+
+// From another TypedArray
+var x = new BigUint64Array([21n, 31n]);
+var y = new BigUint64Array(x);
+console.log(y[0]); // 21n
+
+// From an ArrayBuffer
+var buffer = new ArrayBuffer(32);
+var z = new BigUint64Array(buffer, 0, 4);
+
+// From an iterable
+var iterable = function*(){ yield* [1n, 2n, 3n]; }();
+var biguint64 = new BigUint64Array(iterable);
+// BigUint64Array[1n, 2n, 3n]
+
+ +

Specifications

+ +

BigInt proposal

+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.BigUint64Array")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/boolean/index.html b/files/zh-cn/web/javascript/reference/global_objects/boolean/index.html new file mode 100644 index 0000000000..66b0fb1417 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/boolean/index.html @@ -0,0 +1,120 @@ +--- +title: Boolean +slug: Web/JavaScript/Reference/Global_Objects/Boolean +tags: + - Boolean + - Constructor + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/Boolean +--- +

{{JSRef}}

+ +

Boolean对象是一个布尔值的对象包装器。

+ +

描述

+ +

如果需要,作为第一个参数传递的值将转换为布尔值。如果省略或值0-0,{{jsxref("null")}},false,{{jsxref("NaN")}},{{jsxref("undefined")}},或空字符串(""),该对象具有的初始值false。所有其他值,包括任何对象,空数组([])或字符串"false",都会创建一个初始值为true的对象。

+ +

注意不要将基本类型中的布尔值 true 和 false 与值为 true 和 false 的 Boolean 对象弄混了。

+ +

其值不是{{jsxref("undefined")}}或{{jsxref("null")}}的任何对象(包括其值为false的布尔对象)在传递给条件语句时都将计算为true。 例如,以下{{jsxref("Statements/if...else", "if")}}语句中的条件评估为true

+ +
var x = new Boolean(false);
+if (x) {
+  // 这里的代码会被执行
+}
+
+ +

基本类型的布尔值不受此规则影响。例如下面的 {{jsxref("Statements/if...else", "if")}} 语句的条件为假:

+ +
var x = false;
+if (x) {
+  // 这里的代码不会执行
+}
+
+ +

不要用创建 Boolean 对象的方式将一个非布尔值转化成布尔值,直接将 Boolean 当做转换函数来使用即可,或者使用双重非(!!)运算符

+ +
var x = Boolean(expression);     // 推荐
+var x = !!(expression);          // 推荐
+var x = new Boolean(expression); // 不太好
+
+ +

对于任何对象,即使是值为 falseBoolean 对象,当将其传给 Boolean 函数时,生成的 Boolean 对象的值都是 true

+ +
var myFalse = new Boolean(false);   // true
+var g = new Boolean(myFalse);       // true
+var myString = new String("Hello");
+var s = new Boolean(myString);      // true
+
+ +

最后,不要在应该使用基本类型布尔值的地方使用 Boolean 对象。

+ +
+

注意:当将非标准属性document.all用作此构造函数的参数时,结果是值为false的布尔对象。 此属性是旧属性,是非标准属性,不应使用。

+
+ +

构造器

+ +
+
Boolean()
+
创建一个新的Boolean 对象。
+
+ +

实例方法

+ +
+
{{jsxref("Boolean.prototype.toString()")}}
+
根据对象的值返回字符串"true""false"。 重写{{jsxref("Object.prototype.toString()")}}方法。
+
{{jsxref("Boolean.prototype.valueOf()")}}
+
返回{{jsxref("Boolean")}}对象的原始值。 重写{{jsxref("Object.prototype.valueOf()")}}方法。
+
+ +

示例

+ +

创建值为 false 的 Boolean 对象

+ +
var bNoParam = new Boolean();
+var bZero = new Boolean(0);
+var bNull = new Boolean(null);
+var bEmptyString = new Boolean('');
+var bfalse = new Boolean(false);
+
+ +

创建值为 true 的  Boolean 对象

+ +
var btrue = new Boolean(true);
+var btrueString = new Boolean('true');
+var bfalseString = new Boolean('false');
+var bSuLin = new Boolean('Su Lin');
+var bArrayProto = new Boolean([]);
+var bObjProto = new Boolean({});
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-boolean-objects', 'Boolean')}}
+ +


+ 浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Boolean")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/boolean/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/boolean/prototype/index.html new file mode 100644 index 0000000000..a29fd8eb9a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/boolean/prototype/index.html @@ -0,0 +1,75 @@ +--- +title: Boolean.prototype +slug: Web/JavaScript/Reference/Global_Objects/Boolean/prototype +tags: + - Boolean + - JavaScript + - Property + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Boolean +--- +

{{JSRef}}

+ +

Boolean.prototype 属性表示{{jsxref("Boolean")}} 构造函数的原型。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

{{jsxref("Boolean")}}实例继承自Boolean.prototype。你可以使用构造函数的原型对象向所有{{jsxref("Boolean")}}实例添加属性或方法。

+ +

属性

+ +
+
Boolean.prototype.constructor
+
返回创建了实例原型的函数。默认为{{jsxref("Boolean")}}函数。
+
+ +

方法

+ +
+
{{jsxref("Boolean.prototype.toSource()")}} {{ Non-standard_inline() }}
+
返回包含{{jsxref("Boolean")}}对象源码的字符串;你可以使用这个字符串来创建一个等价的对象。覆盖了{{jsxref("Object.prototype.toSource()")}} 方法。
+
{{jsxref("Boolean.prototype.toString()")}}
+
根据对象的值来返回一个字符串:"true""false"。覆盖了 {{jsxref("Object.prototype.toString()")}} 方法。
+
{{jsxref("Boolean.prototype.valueOf()")}}
+
返回{{jsxref("Boolean")}}对象的原始值。覆盖了 {{jsxref("Object.prototype.valueOf()")}} 方法。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.6.3.1', 'Boolean.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-boolean.prototype', 'Boolean.prototype')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-boolean.prototype', 'Boolean.prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Boolean.prototype")}}

diff --git a/files/zh-cn/web/javascript/reference/global_objects/boolean/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/boolean/tosource/index.html new file mode 100644 index 0000000000..2086ce07c6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/boolean/tosource/index.html @@ -0,0 +1,59 @@ +--- +title: Boolean.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/Boolean/toSource +tags: + - JavaScript + - Method + - Prototype + - 布尔 +translation_of: Web/JavaScript/Reference/Global_Objects/Boolean/toSource +--- +
{{JSRef}} {{non-standard_header}}
+ +

toSource()方法返回一个表示对象的源码的字符串。

+ +

语法

+ +
booleanObj.toSource()
+Boolean.toSource()
+ +

返回值

+ +

表示对象的源码的字符串。

+ +

描述

+ +

toSource方法返回以下值:

+ + + +

此方法通常由JavaScript在内部调用,而不是在代码中显式调用。

+ +

规范

+ +

不是任何标准的一部分。 在JavaScript 1.3中实现。

+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Boolean.toSource")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/boolean/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/boolean/tostring/index.html new file mode 100644 index 0000000000..6245e953dc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/boolean/tostring/index.html @@ -0,0 +1,87 @@ +--- +title: Boolean.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/Boolean/toString +tags: + - Boolean + - JavaScript + - Method + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Boolean/toString +--- +
{{JSRef}}
+ +

toString() 方法返回指定的布尔对象的字符串形式。

+ +
{{EmbedInteractiveExample("pages/js/boolean-tostring.html")}}
+ + + +

语法

+ +
bool.toString()
+ +

返回值

+ +

表示特定{{jsxref("Boolean")}}对象的字符串。

+ +

描述

+ +

{{jsxref("Boolean")}} 对象覆盖了 {{jsxref("Object")}} 对象的  toString 方法。并没有继承 {{jsxref("Object.prototype.toString()")}}。对于布尔对象,toString 方法返回该对象的字符串形式。

+ +

当一个{{jsxref("Boolean")}}对象作为文本值或进行字符串连接时,JavaScript 会自动调用其 toString 方法。

+ +

对于{{jsxref("Boolean")}}对象或值,内置的 toString 方法返回字符串 "true" 或 "false",具体返回哪个取决于布尔对象的值。

+ +

示例

+ +

使用 toString

+ +

下面的代码,flag.toString 返回 "true":

+ +
var flag = new Boolean(true)
+var myVar = flag.toString()
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.6.4.2', 'Boolean.prototype.toString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-boolean.prototype.tostring', 'Boolean.prototype.toString')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-boolean.prototype.tostring', 'Boolean.prototype.toString')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Boolean.toString")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/boolean/valueof/index.html b/files/zh-cn/web/javascript/reference/global_objects/boolean/valueof/index.html new file mode 100644 index 0000000000..068e594b92 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/boolean/valueof/index.html @@ -0,0 +1,83 @@ +--- +title: Boolean.prototype.valueOf() +slug: Web/JavaScript/Reference/Global_Objects/Boolean/valueOf +tags: + - Boolean + - JavaScript + - Method + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Boolean/valueOf +--- +
{{JSRef}}
+ +

valueOf() 方法返回一个{{jsxref("Boolean")}}对象的原始值。

+ +
{{EmbedInteractiveExample("pages/js/boolean-valueof.html")}}
+ + + +

语法

+ +
bool.valueOf()
+ +

返回值

+ +

给定{{jsxref("Boolean")}}对象的原始值

+ +

描述

+ +

{{jsxref("Boolean")}}的 valueOf 方法返回一个{{jsxref("Boolean")}}对象或{{jsxref("Boolean")}}字面量的原始值作为布尔数据类型。

+ +

该方法通常在 JavaScript 内部调用,而不是在代码中显式调用。

+ +

示例

+ +

使用 valueOf

+ +
x = new Boolean();
+myVar = x.valueOf()      // assigns false to myVar
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.6.4.3', 'Boolean.prototype.valueOf')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-boolean.prototype.valueof', 'Boolean.prototype.valueOf')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-boolean.prototype.valueof', 'Boolean.prototype.valueOf')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Boolean.valueOf")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/buffer/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/buffer/index.html new file mode 100644 index 0000000000..a8324d6dd2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/buffer/index.html @@ -0,0 +1,64 @@ +--- +title: DataView.prototype.buffer +slug: Web/JavaScript/Reference/Global_Objects/DataView/buffer +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/buffer +--- +
{{JSRef}}
+ +

 buffer 属性描述了在构造时被 DataView 引用的 {{jsxref("ArrayBuffer")}}。

+ +
{{EmbedInteractiveExample("pages/js/dataview-buffer.html")}}
+ + + +

语法

+ +
dataview.buffer
+ +

描述

+ +

buffer 属性是一个访问器(accessor)属性,它的 set 属性为 undefined,这意味着它是只读的。值在 DataView 被创建时就确定了,且不能改变。

+ +

示例

+ +

使用buffer属性

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.buffer; // ArrayBuffer { byteLength: 8 }
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-dataview.prototype.buffer', 'DataView.prototype.buffer')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-get-dataview.prototype.buffer', 'DataView.prototype.buffer')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView.buffer")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/bytelength/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/bytelength/index.html new file mode 100644 index 0000000000..a581506c44 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/bytelength/index.html @@ -0,0 +1,70 @@ +--- +title: DataView.prototype.byteLength +slug: Web/JavaScript/Reference/Global_Objects/DataView/byteLength +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/byteLength +--- +
{{JSRef}}
+ +

 byteLength 属性描述了视图从它的 {{jsxref("ArrayBuffer")}} 开始的字节长度。

+ +
{{EmbedInteractiveExample("pages/js/dataview-bytelength.html")}}
+ + + +

语法

+ +
dataview.byteLength
+ +

描述

+ +

byteLength 属性是一个获取(accessor)属性,它的 set 属性为 undefined,这意味着它是只读的。值在 DataView 被创建时就确定了,且不能改变。如果 DataView 没有指定偏移量或byteLength,那么被引用的 ArrayBuffer 的字节长度将被返回。

+ +

Examples

+ +

Using the byteLength property

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.byteLength; // 8 (matches the byteLength of the buffer)
+
+var dataview2 = new DataView(buffer, 1, 5);
+dataview2.byteLength; // 5 (as specified when constructing the DataView)
+
+var dataview3 = new DataView(buffer, 2);
+dataview3.byteLength; // 6 (due to the offset of the constructed DataView)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-dataview.prototype.bytelength', 'DataView.prototype.byteLength')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-get-dataview.prototype.bytelength', 'DataView.prototype.byteLength')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView.byteLength")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/byteoffset/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/byteoffset/index.html new file mode 100644 index 0000000000..9335006969 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/byteoffset/index.html @@ -0,0 +1,67 @@ +--- +title: DataView.prototype.byteOffset +slug: Web/JavaScript/Reference/Global_Objects/DataView/byteOffset +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/byteOffset +--- +
{{JSRef}}
+ +

 byteOffset 属性描述了从 {{jsxref("ArrayBuffer")}} 开始的字节偏移量。

+ +
{{EmbedInteractiveExample("pages/js/dataview-byteoffset.html")}}
+ + + +

语法

+ +
dataview.byteOffset
+ +

描述

+ +

 byteOffset 属性是一个获取(accessor)属性,它的 set 属性为 undefined,这意味着它是只读的。值在 DataView 被创建时就确定了,且不能改变。

+ +

示例

+ +

使用 byteOffset 属性

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.byteOffset; // 0 (没有指定偏移量)
+
+var dataview2 = new DataView(buffer, 3);
+dataview2.byteOffset; // 3 (在构造DataView时指定)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-dataview.prototype.byteoffset', 'DataView.prototype.byteOffset')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-get-dataview.prototype.byteoffset', 'DataView.prototype.byteOffset')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView.byteOffset")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getbigint64/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getbigint64/index.html new file mode 100644 index 0000000000..cf90669761 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getbigint64/index.html @@ -0,0 +1,91 @@ +--- +title: getBigInt64() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getBigInt64 +tags: + - DataView + - JavaScript + - Prototype + - getBigInt64() + - 大整型 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getBigInt64 +--- +
{{JSRef}}
+ +
+ +

getBigInt64() 方法从 {{jsxref("DataView")}}开始获取一个指定偏移量的有符号64位整数 (long long) 。

+ +
{{EmbedInteractiveExample("pages/js/dataview-getbigint64.html")}}
+ + + +

语法

+ +
dataview.getBigInt64(byteOffset [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量,以字节为单位。指明视图开始读取数据的偏移量。
+
littleEndian
+
{{optional_inline}} 指明该64位整型数值的存储方式( {{Glossary("Endianness", "大小端模式")}}) 。 如果为 false 或 undefined, 则按大端方式读取数据。
+
+ +

返回值

+ +

一个 {{jsxref("BigInt")}}.

+ +

异常抛出

+ +
+
{{jsxref("RangeError")}}
+
如果 byteOffset 设置的偏移量超出了视图的范围,则抛出该异常。
+
+ +

简介

+ + + +

例子

+ +

使用 getBigInt64 方法

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getBigInt64(0); // 0n
+
+ +

规范

+ + + + + + + + + + + + + + +
规范版本规范状态注解      
DataView.prototype.getBigInt64 proposal
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView.getBigInt64")}}

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getbiguint64/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getbiguint64/index.html new file mode 100644 index 0000000000..d418df1366 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getbiguint64/index.html @@ -0,0 +1,80 @@ +--- +title: DataView.prototype.getBigUint64() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getBigUint64 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getBigUint64 +--- +
{{JSRef}}
+ +

getBigUint64()方法,从{{jsxref("DataView")}}的指定偏移量位置获取一个无符号64位整数(unsigned long long)。

+ +
{{EmbedInteractiveExample("pages/js/dataview-getbiguint64.html")}}
+ + + +

语法

+ +
dataview.getBigUint64(byteOffset [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量,按字节偏移,从DataView读取一个整数
+
littleEndian
+
{{optional_inline}} 指出64位整数以 {{Glossary("Endianness", "little- or big-endian")}} 类型存储. 如果值为 false or undefined, 读取一个大端数值.
+
+ +

返回值

+ +

A {{jsxref("BigInt")}}.

+ +

异常

+ +
+
{{jsxref("RangeError")}}
+
Thrown if the byteOffset is set such that it would read beyond the end of the view.
+
+ +

Description

+ +

There is no alignment constraint; multi-byte values may be fetched from any offset.

+ +

Examples

+ +

Using the getBigUint64 method

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getBigUint64(0); // 0n
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
DataView.prototype.getBigUint64 proposal
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.DataView.getBigUint64")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getfloat32/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getfloat32/index.html new file mode 100644 index 0000000000..b43d4df38c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getfloat32/index.html @@ -0,0 +1,94 @@ +--- +title: DataView.prototype.getFloat32() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getFloat32 +tags: + - DataView + - getFloat32 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getFloat32 +--- +
{{JSRef}}
+ +

getFloat32()方法从相对于{{jsxref("DataView")}} 的起始位置偏移 n 个字节处获取一个32-bit浮点数(单精度浮点数,4个字节).

+ +
{{EmbedInteractiveExample("pages/js/dataview-getfloat32.html")}}
+ + + +

语法

+ +
dataview.getFloat32(byteOffset [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量, 单位为字节, 为从视图的开始位置到读取数值的位置的偏移。
+
littleEndian
+
{{optional_inline}} 表示这个32位浮点数是否以 {{Glossary("Endianness", "little- or big-endian")}} 格式存储,如果设置为 false 或者不指定,将用big-endian格式读取数值。
+
+ +

返回

+ +
+
一个带符号的32位浮点数。
+
+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset 设置导致读数值时超出了视图的末尾就会抛出错误。
+
+ +

说明

+ +
+
没有对齐约束; 多字节值可以从任何偏移处获取。
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getFloat32(1); // 0
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.getfloat32', 'DataView.prototype.getFloat32')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.getfloat32', 'DataView.prototype.getFloat32')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.getFloat32")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getfloat64/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getfloat64/index.html new file mode 100644 index 0000000000..885acb9421 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getfloat64/index.html @@ -0,0 +1,91 @@ +--- +title: DataView.prototype.getFloat64() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getFloat64 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getFloat64 +--- +
{{JSRef}}
+ +

getFloat64()方法DataView相对于起始位置偏移 n 个字节处开始,获取一个64-bit数(双精度浮点型,8个字节).

+ +
{{EmbedInteractiveExample("pages/js/dataview-getfloat64.html")}}
+ + + +

语法

+ +
dataview.getFloat64(byteOffset [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量, 单位为字节, 从头开始计算.
+
littleEndian
+
{{optional_inline}} Indicates whether the 64-bit float is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is read.
+
+ +

返回

+ +
+
一个双精度浮点型64位数.
+
+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

描述

+ +
+
没有对齐约束; 多字节值可以从任何偏移量获取.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getFloat64(1); // 0
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.getfloat64', 'DataView.prototype.getFloat64')}}{{Spec2('ES6')}}Initial definition in ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.getfloat64', 'DataView.prototype.getFloat64')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.getFloat64")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getint16/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getint16/index.html new file mode 100644 index 0000000000..060f88b722 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getint16/index.html @@ -0,0 +1,94 @@ +--- +title: DataView.prototype.getInt16() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getInt16 +tags: + - 类型化 + - 类型化数组 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getInt16 +--- +
{{JSRef}}
+ +

getInt16()方法{{jsxref("DataView")}}相对于起始位置偏移 n 个字节处开始,获取一个16-bit数(短整型,2个字节).

+ +
{{EmbedInteractiveExample("pages/js/dataview-getint16.html")}}
+ + + +

语法

+ +
dataview.getInt16(byteOffset [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量, 单位为字节, 从头开始计算.
+
littleEndian
+
{{optional_inline}} 表示该 16 位整数是否以 {{Glossary("Endianness", "little- or big-endian")}} 格式存储的(就是使用的字节序格式,具体参考链接页面);如果传入的值为 true,就表示使用 little-endian(低字节序),如果传入的值为 false 或者 undefined,则会使用 big-endian(高字节序) 方式读值。
+
+ +

返回

+ +
+
一个短整型16位数.
+
+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

描述

+ +
+
 没有对齐约束; 多字节值可以从任何偏移量获取.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getInt16(1); // 0
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.getint16', 'DataView.prototype.getInt16')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.getint16', 'DataView.prototype.getInt16')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.getInt16")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getint32/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getint32/index.html new file mode 100644 index 0000000000..616d2b1977 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getint32/index.html @@ -0,0 +1,91 @@ +--- +title: DataView.prototype.getInt32() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getInt32 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getInt32 +--- +
{{JSRef}}
+ +

getInt32()方法DataView相对于起始位置偏移 n 个字节处开始,获取一个32-bit数(长整型,4个字节).

+ +
{{EmbedInteractiveExample("pages/js/dataview-getint32.html")}}
+ + + +

语法

+ +
dataview.getInt32(byteOffset [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量, 单位为字节, 从头开始计算.
+
littleEndian
+
{{optional_inline}} Indicates whether the 32-bit int is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is read.
+
+ +

返回

+ +
+
一个长整型32位数.
+
+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

描述

+ +
+
 没有对齐约束; 多字节值可以从任何偏移量获取.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getInt32(1); // 0
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.getint32', 'DataView.prototype.getInt32')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.getint32', 'DataView.prototype.getInt32')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.getInt32")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getint8/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getint8/index.html new file mode 100644 index 0000000000..0a8a5da6a2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getint8/index.html @@ -0,0 +1,86 @@ +--- +title: DataView.prototype.getInt8() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getInt8 +tags: + - 类型化 + - 类型化数组 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getInt8 +--- +
{{JSRef}}
+ +

getInt8()方法{{jsxref("DataView")}}相对于起始位置偏移 n 个字节处开始,获取一个有符号的 8-bit 整数(一个字节)。

+ +
{{EmbedInteractiveExample("pages/js/dataview-getint8.html")}}
+ + + +

语法

+ +
dataview.getInt8(byteOffset)
+ +

参数

+ +
+
byteOffset
+
偏移量, 单位为字节, 从起始位置开始计算.
+
+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

描述

+ +
+
 没有对齐约束; 多字节值可以从任何偏移量获取.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getInt8(1); // 0
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.getint8', 'DataView.prototype.getInt8')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.getint8', 'DataView.prototype.getInt8')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView.getInt8")}}

+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getuint16/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getuint16/index.html new file mode 100644 index 0000000000..6ed5b252da --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getuint16/index.html @@ -0,0 +1,94 @@ +--- +title: DataView.prototype.getUint16() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getUint16 +tags: + - 类型化 + - 类型化数组 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getUint16 +--- +
{{JSRef}}
+ +

getUint16()方法DataView相对于起始位置偏移 n 个字节处开始,获取一个16-bit数(无符号短整型,2个字节).

+ +
{{EmbedInteractiveExample("pages/js/dataview-getuint16.html")}}
+ + + +

语法

+ +
dataview.getUint16(byteOffset [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量, 单位为字节, 从头开始计算.
+
littleEndian
+
{{optional_inline}} Indicates whether the 16-bit int is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is read.
+
+ +

返回

+ +
+
一个无符号短整型16位数.
+
+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

描述

+ +
+
没有对齐约束; 多字节值可以从任何偏移量获取.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getUint16(1); // 0
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.getuint16', 'DataView.prototype.getUint16')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.getuint16', 'DataView.prototype.getUint16')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.getUint16")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getuint32/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getuint32/index.html new file mode 100644 index 0000000000..3affb0312a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getuint32/index.html @@ -0,0 +1,91 @@ +--- +title: DataView.prototype.getUint32() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getUint32 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getUint32 +--- +
{{JSRef}}
+ +

getUint32()方法DataView相对于起始位置偏移 n 个字节处开始,获取一个32-bit数(无符号长整型,4个字节).

+ +
{{EmbedInteractiveExample("pages/js/dataview-getuint32.html")}}
+ + + +

语法

+ +
dataview.getUint32(byteOffset [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量, 单位为字节, 从头开始计算.
+
littleEndian
+
{{optional_inline}} Indicates whether the 32-bit int is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is read.
+
+ +

返回

+ +
+
一个无符号长整型32位数.
+
+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

描述

+ +
+
没有对齐约束; 多字节值可以从任何偏移量获取.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getUint32(1); // 0
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.getuint32', 'DataView.prototype.getUint32')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.getuint32', 'DataView.prototype.getUint32')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.getUint32")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/getuint8/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/getuint8/index.html new file mode 100644 index 0000000000..4e26ade311 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/getuint8/index.html @@ -0,0 +1,86 @@ +--- +title: DataView.prototype.getUint8() +slug: Web/JavaScript/Reference/Global_Objects/DataView/getUint8 +tags: + - 类型化 + - 类型化数组 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/getUint8 +--- +
{{JSRef}}
+ +

getUint8()方法{{jsxref("DataView")}}相对于起始位置偏移 n 个字节处开始,获取一个无符号的8-bit整数(一个字节).

+ +
{{EmbedInteractiveExample("pages/js/dataview-getuint8.html")}}
+ + + +

语法

+ +
dataview.getUint8(byteOffset)
+ +

参数

+ +
+
byteOffset
+
偏移量, 单位为字节, 从头开始计算.
+
+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

描述

+ +
+
 没有对齐约束; 多字节值可以从任何偏移量获取.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.getUint8(1); // 0
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.getuint8', 'DataView.prototype.getUint8')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.getuint8', 'DataView.prototype.getUint8')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView.getUint8")}}

+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/index.html new file mode 100644 index 0000000000..7bd1755475 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/index.html @@ -0,0 +1,166 @@ +--- +title: DataView +slug: Web/JavaScript/Reference/Global_Objects/DataView +tags: + - DataView + - JavaScript + - TypedArrays + - 构造器 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView +--- +
{{JSRef}}
+ +

DataView 视图是一个可以从 二进制{{jsxref("ArrayBuffer")}} 对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的字节序问题。

+ +
{{EmbedInteractiveExample("pages/js/dataview-constructor.html")}}
+ + + +

语法

+ +
new DataView(buffer [, byteOffset [, byteLength]])
+ +

参数

+ +
+
buffer
+
一个 已经存在的{{jsxref("ArrayBuffer")}} 或 {{jsxref("SharedArrayBuffer")}} {{experimental_inline}} 对象,DataView 对象的数据源。
+
byteOffset {{optional_inline}}
+
DataView 对象的第一个字节在 buffer 中的字节偏移。如果未指定,则默认从第一个字节开始。
+
byteLength {{optional_inline}}
+
此 DataView 对象的字节长度。如果未指定,这个视图的长度将匹配buffer的长度。
+
+ +

返回值

+ +

一个表示指定数据缓存区的新DataView 对象。(这句话也许不是非常有助于说明清楚)

+ +

你可以把返回的对象想象成一个二进制字节缓存区 array buffer 的“解释器”——它知道如何在读取或写入时正确地转换字节码。这意味着它能在二进制层面处理整数与浮点转化、字节顺序等其他有关的细节问题。

+ +

异常

+ +
+
{{jsxref("RangeError")}}
+
如果 byteOffset 或者 byteLength 参数的值导致视图超出了 buffer 的结束位置就会抛出此异常。
+ 例如,假设 buffer (缓冲对象)是 16 字节长度,byteOffset 参数为 8,byteLength 参数为 10,这个错误就会抛出,这是因为结果视图试图超出 buffer 对象的总长度 2 个字节。
+
+ +

描述

+ +

Endianness(字节序)

+ +

需要多个字节来表示的数值,在存储时其字节在内存中的相对顺序依据平台架构的不同而不同,参照 {{Glossary("Endianness")}}。而使用 DataView 的访问函数时,不需要考虑平台架构中所使用的是哪种字节序。

+ +
var littleEndian = (function() {
+  var buffer = new ArrayBuffer(2);
+  new DataView(buffer).setInt16(0, 256, true /* 设置值时,使用小端字节序 */);
+  // Int16Array 使用系统字节序(由此可以判断系统字节序是否为小端字节序)
+  return new Int16Array(buffer)[0] === 256;
+})();
+console.log(littleEndian); // 返回 true 或 false
+
+ +

64 位整数值

+ +

因为 JavaScript 目前不包含对 64 位整数值支持的标准,所以 DataView 不提供原生的 64 位操作。作为变通,您可以实现自己的 getUint64() 函数,以获得精度高达 {{jsxref("Number.MAX_SAFE_INTEGER")}} 的值,可以满足某些特定情况的需求。

+ +
function getUint64(dataview, byteOffset, littleEndian) {
+  // 将 64 位整数值分成两份 32 位整数值
+  const left =  dataview.getUint32(byteOffset, littleEndian);
+  const right = dataview.getUint32(byteOffset+4, littleEndian);
+
+  // 合并两个 32 位整数值
+  const combined = littleEndian? left + 2**32*right : 2**32*left + right;
+
+  if (!Number.isSafeInteger(combined))
+    console.warn(combined, 'exceeds MAX_SAFE_INTEGER. Precision may be lost');
+
+  return combined;
+}
+
+ +

或者,如果需要填满 64 位,可以创建一个 {{jsxref("BigInt")}}。此外,尽管原生 BigInt 要比用户端的库中模拟的 BigInt 快得多,但在 JavaScript 中,BigInt 总是比 32 位整数慢得多,这是因为 BigInt 的大小是可变的。

+ +
const BigInt = window.BigInt, bigThirtyTwo = BigInt(32), bigZero = BigInt(0);
+function getUint64BigInt(dataview, byteOffset, littleEndian) {
+  // 将 64 位整数值分成两份 32 位整数值
+  const left = BigInt(dataview.getUint32(byteOffset|0, !!littleEndian)>>>0);
+  const right = BigInt(dataview.getUint32((byteOffset|0) + 4|0, !!littleEndian)>>>0);
+
+  // 合并两个 32 位整数值并返回
+  return littleEndian ? (right<<bigThirtyTwo)|left : (left<<bigThirtyTwo)|right;
+}
+ +

属性

+ +

所有 DataView 实例都继承自 {{jsxref("DataView.prototype")}},并且允许向 DataView 对象中添加额外属性。

+ +
{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/DataView/prototype', '属性')}}
+ +

方法

+ +
{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/DataView/prototype', '方法')}}
+ +

示例

+ +
var buffer = new ArrayBuffer(16);
+var view = new DataView(buffer, 0);
+
+view.setInt16(1, 42);
+view.getInt16(1); // 42
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范名称状态注释
{{SpecName('ESDraft', '#sec-dataview-constructor', 'DataView')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-dataview-constructor', 'DataView')}}{{Spec2('ES6')}}ECMA 标准中的初始版本
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView")}}

+ +

兼容性提示

+ +

从 FireFox 40 开始,DataView 对象需要通过 {{jsxref("Operators/new", "new")}} 操作符来构造。如果不使用 new 而是直接将 DataView() 作为函数调用的话,会抛出 {{jsxref("TypeError")}} 异常。

+ +
var dv = DataView(buffer, 0);
+// 抛出异常,错误信息翻译为:禁止在不用 new 的情况下直接调用 DataView 的构造函数。
+// TypeError: calling a builtin DataView constructor without new is forbidden
+ +
var dv = new DataView(buffer, 0);
+ +

请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/prototype/index.html new file mode 100644 index 0000000000..84488ad734 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/prototype/index.html @@ -0,0 +1,102 @@ +--- +title: DataView.prototype +slug: Web/JavaScript/Reference/Global_Objects/DataView/prototype +tags: + - DataView属性 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView +--- +
{{JSRef}}
+ +

DataView.prototype 表示{{jsxref("DataView")}}的原型

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

DataView 的实例从DataView.prototype继承。就像所有的构造器,你可以修改原型来改变生成的DataView实例。

+ +

属性

+ +
+
{{jsxref("DataView.prototype.constructor")}}
+
指定用来生成原型的构造函数.初始化值是标准内置DataView构造器.
+
{{jsxref("DataView.prototype.buffer")}} {{readonlyInline}}
+
被视图引入的{{jsxref("ArrayBuffer")}}.创建实例的时候已固化因此是只读的.
+
{{jsxref("DataView.prototype.byteLength")}} {{readonlyInline}}
+
从 {{jsxref("ArrayBuffer")}}中读取的字节长度. 创建实例的时候已固化因此是只读的.
+
{{jsxref("DataView.prototype.byteOffset")}} {{readonlyInline}}
+
从 {{jsxref("ArrayBuffer")}}读取时的偏移字节长度. 创建实例的时候已固化因此是只读的.
+
+ +

方法

+ +

+ +
+
{{jsxref("DataView.prototype.getInt8()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个8-bit数(一个字节).
+
{{jsxref("DataView.prototype.getUint8()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个8-bit数(无符号字节).
+
{{jsxref("DataView.prototype.getInt16()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个16-bit数(短整型).
+
{{jsxref("DataView.prototype.getUint16()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个16-bit数(无符号短整型).
+
{{jsxref("DataView.prototype.getInt32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(长整型).
+
{{jsxref("DataView.prototype.getUint32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(无符号长整型).
+
{{jsxref("DataView.prototype.getFloat32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(浮点型).
+
{{jsxref("DataView.prototype.getFloat64()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个64-bit数(双精度浮点型).
+
+ +

+ +
+
{{jsxref("DataView.prototype.setInt8()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(一个字节).
+
{{jsxref("DataView.prototype.setUint8()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(无符号字节).
+
{{jsxref("DataView.prototype.setInt16()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(短整型).
+
{{jsxref("DataView.prototype.setUint16()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(无符号短整型).
+
{{jsxref("DataView.prototype.setInt32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(长整型).
+
{{jsxref("DataView.prototype.setUint32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(无符号长整型).
+
{{jsxref("DataView.prototype.setFloat32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(浮点型).
+
{{jsxref("DataView.prototype.setFloat64()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个64-bit数(双精度浮点型).
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-dataview.prototype', 'DataView.prototype')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.prototype")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setbigint64/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setbigint64/index.html new file mode 100644 index 0000000000..5e9b6596d4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setbigint64/index.html @@ -0,0 +1,84 @@ +--- +title: DataView.prototype.setBigInt64() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setBigInt64 +tags: + - BigInt + - DataView + - setBigInt64 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setBigInt64 +--- +
{{JSRef}}
+ +

setBigInt64()方法在距{{jsxref("DataView")}} 的起始位置的指定字节偏移处存储一个带符号的64位整数(long long类型)值。

+ +
{{EmbedInteractiveExample("pages/js/dataview-setbigint64.html")}}
+ + + +

语法

+ +
dataview.setBigInt64(byteOffset, value [, littleEndian])
+ +

参数说明

+ +
+
byteOffset
+
字节偏移量,为从视图的起始位置到数据存储位置的字节字节偏移量。
+
+
value
+
作为一个{{jsxref("BigInt")}}类型设置的数值。满足一个带符号的64位整数的最大可能数值是 2n ** (64n -1n) - 1n (9223372036854775807n)。当发生溢出时,将会变成负数(-9223372036854775808n)。
+
littleEndian
+
{{optional_inline}} 为可选参数,表示这个64位整数是否以{{Glossary("Endianness", "little-endian 或者big-endian")}}格式存储。如果设置为false 或者未指定(undefined),将会写入一个big-endian(大端模式:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端)格式的数值。
+
+ +

返回值

+ +

{{jsxref("undefined")}}.

+ +

抛出的错误

+ +
+
{{jsxref("RangeError")}}
+
如果 byteOffset设置导致存储该数值时超出了视图的末尾位置,将会抛出错误。
+
+ +

例子

+ +

使用 setBigInt64 方法

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setBigInt64(0, 3n);
+dataview.getBigInt64(0); // 3n
+
+ +

相关规范

+ + + + + + + + + + + + + + +
规范状态解释
{{SpecName('ESDraft', '#sec-dataview.prototype.setbigint64', 'DataView.prototype.setBigInt64()')}}{{Spec2('ESDraft')}}    
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView.setBigInt64")}}

+ +

请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setbiguint64/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setbiguint64/index.html new file mode 100644 index 0000000000..bd2bfef8f4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setbiguint64/index.html @@ -0,0 +1,83 @@ +--- +title: DataView.prototype.setBigUint64() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setBigUint64 +tags: + - BigInt + - DataView + - setBigUint64 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setBigUint64 +--- +
{{JSRef}}
+ +

setBigUint64() 方法在距DataView 的起始位置的指定字节偏移处存储一个无符号的64位整数(unsigned  long long类型)值。

+ +
{{EmbedInteractiveExample("pages/js/dataview-setbiguint64.html")}}
+ + + +

语法

+ +
dataview.setBigUint64(byteOffset, value [, littleEndian])
+ +

参数说明

+ +
+
byteOffset
+
字节偏移量,为从视图的起始位置到数据存储位置的字节字节偏移量。
+
value
+
作为一个BigInt类型设置的数值。满足一个无符号的64位整数的最大可能数值是 2n ** 64n - 1n (18446744073709551615n)。当发生溢出时,将会变成0。
+
littleEndian
+
为可选参数,表示这个64位整数是否以little-endian 或者big-endian格式存储。如果设置为false 或者未指定(undefined),将会写入一个big-endian(大端模式:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端)格式的数值。
+
+ +

返回值

+ +

{{jsxref("undefined")}}.

+ +

抛出的错误

+ +
+
{{jsxref("RangeError")}}
+
如果 byteOffset设置导致存储该数值时超出了视图的末尾位置,将会抛出错误。
+
+ +

例子

+ +

使用 setBigUint64 方法

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setBigUint64(0, 3n);
+dataview.getBigUint64(0); // 3n
+
+ +

相关规范 

+ + + + + + + + + + + + + + +
规范状态解释
{{SpecName('ESDraft', '#sec-dataview.prototype.setbiguint64', 'DataView.prototype.setBigUint64()')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView.setBigUint64")}}

+ +

请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setfloat32/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setfloat32/index.html new file mode 100644 index 0000000000..418718aef2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setfloat32/index.html @@ -0,0 +1,86 @@ +--- +title: DataView.prototype.setFloat32() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setFloat32 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setFloat32 +--- +
{{JSRef}}
+ +

setFloat32()DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(浮点型).

+ +

{{EmbedInteractiveExample("pages/js/dataview-setfloat32.html")}}

+ + + +

语法

+ +
dataview.setFloat32(byteOffset, value [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量,从头开始计算,单位为字节.
+
value
+
设置的数值.
+
littleEndian
+
{{optional_inline}} Indicates whether the 32-bit float is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is written.
+
+ +

返回

+ +

{{jsxref("undefined")}}.

+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setFloat32(1, 3);
+dataview.getFloat32(1); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.setfloat32', 'DataView.prototype.setFloat32')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.setfloat32', 'DataView.prototype.setFloat32')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.setFloat32")}}

+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setfloat64/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setfloat64/index.html new file mode 100644 index 0000000000..1f46fddbf0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setfloat64/index.html @@ -0,0 +1,86 @@ +--- +title: DataView.prototype.setFloat64() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setFloat64 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setFloat64 +--- +
{{JSRef}}
+ +

setFloat64()DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个64-bit数(双精度浮点型).

+ +
{{EmbedInteractiveExample("pages/js/dataview-setfloat64.html")}}
+ + + +

语法

+ +
dataview.setFloat64(byteOffset, value [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量,从头开始计算,单位为字节.
+
value
+
设置的数值.
+
littleEndian
+
{{optional_inline}} Indicates whether the 64-bit float is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is written.
+
+ +

返回

+ +

{{jsxref("undefined")}}.

+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setFloat64(0, 3);
+dataview.getFloat64(0); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.setfloat64', 'DataView.prototype.setFloat64')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.setfloat64', 'DataView.prototype.setFloat64')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.setFloat64")}}

+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setint16/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setint16/index.html new file mode 100644 index 0000000000..92d8deb975 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setint16/index.html @@ -0,0 +1,86 @@ +--- +title: DataView.prototype.setInt16() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setInt16 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setInt16 +--- +
{{JSRef}}
+ +

setInt16()DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(短整型).

+ +
{{EmbedInteractiveExample("pages/js/dataview-setint16.html")}}
+ + + +

语法

+ +
dataview.setInt16(byteOffset, value [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量,从头开始计算,单位为字节.
+
value
+
设置的数值.
+
littleEndian
+
{{optional_inline}} Indicates whether the 16-bit int is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is written.
+
+ +

返回

+ +

{{jsxref("undefined")}}.

+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setInt16(1, 3);
+dataview.getInt16(1); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.setint16', 'DataView.prototype.setInt16')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.setint16', 'DataView.prototype.setInt16')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.setInt16")}}

+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setint32/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setint32/index.html new file mode 100644 index 0000000000..0bbd9d2b7f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setint32/index.html @@ -0,0 +1,86 @@ +--- +title: DataView.prototype.setInt32() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setInt32 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setInt32 +--- +
{{JSRef}}
+ +

setInt32()DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(长整型).

+ +
{{EmbedInteractiveExample("pages/js/dataview-setint32.html")}}
+ + + +

语法

+ +
dataview.setInt32(byteOffset, value [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量,从头开始计算,单位为字节.
+
value
+
设置的数值.
+
littleEndian
+
{{optional_inline}} Indicates whether the 32-bit int is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is written.
+
+ +

返回

+ +

{{jsxref("undefined")}}.

+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setInt32(1, 3);
+dataview.getInt32(1); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.setint32', 'DataView.prototype.setInt32')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.setint32', 'DataView.prototype.setInt32')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.setInt32")}}

+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setint8/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setint8/index.html new file mode 100644 index 0000000000..dc7c7b30e4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setint8/index.html @@ -0,0 +1,80 @@ +--- +title: DataView.prototype.setInt8() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setInt8 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setInt8 +--- +
{{JSRef}}
+ +

setInt8()DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(一个字节).

+ +
{{EmbedInteractiveExample("pages/js/dataview-setint8.html")}}
+ + + +

语法

+ +
dataview.setInt8(byteOffset, value)
+ +

参数

+ +
+
byteOffset
+
偏移量,从头开始计算,单位为字节
+
value
+
设置的整数值
+
+

返回

+ +

{{jsxref("undefined")}}.

+
+
+ +

抛出的错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setInt8(1, 3);
+dataview.getInt8(1); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.setint8', 'DataView.prototype.setInt8')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.DataView.setInt8")}}

+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setuint16/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setuint16/index.html new file mode 100644 index 0000000000..4bcfd257e3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setuint16/index.html @@ -0,0 +1,86 @@ +--- +title: DataView.prototype.setUint16() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setUint16 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setUint16 +--- +
{{JSRef}}
+ +

setUint16()DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(无符号短整型).

+ +
{{EmbedInteractiveExample("pages/js/dataview-setuint16.html")}}
+ + + +

语法

+ +
dataview.setUint16(byteOffset, value [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量,从头开始计算,单位为字节.
+
value
+
设置的数值.
+
littleEndian
+
{{optional_inline}} Indicates whether the 16-bit int is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is written.
+
+ +

返回

+ +

{{jsxref("undefined")}}.

+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setUint16(1, 3);
+dataview.getUint16(1); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.setuint16', 'DataView.prototype.setUint16')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.setuint16', 'DataView.prototype.setUint16')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.setUint16")}}

+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setuint32/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setuint32/index.html new file mode 100644 index 0000000000..73857cb03c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setuint32/index.html @@ -0,0 +1,86 @@ +--- +title: DataView.prototype.setUint32() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setUint32 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setUint32 +--- +
{{JSRef}}
+ +

setUint32()DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(无符号长整型).

+ +
{{EmbedInteractiveExample("pages/js/dataview-setuint32.html")}}
+ + + +

语法

+ +
dataview.setUint32(byteOffset, value [, littleEndian])
+ +

参数

+ +
+
byteOffset
+
偏移量,从头开始计算,单位为字节.
+
value
+
设置的数值.
+
littleEndian
+
{{optional_inline}} Indicates whether the 32-bit int is stored in {{Glossary("Endianness", "little- or big-endian")}} format. If false or undefined, a big-endian value is written.
+
+ +

返回

+ +

{{jsxref("undefined")}}.

+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setUint32(1, 3);
+dataview.getUint32(1); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.setuint32', 'DataView.prototype.setUint32')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.setuint32', 'DataView.prototype.setUint32')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.setUint32")}}

+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/setuint8/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/setuint8/index.html new file mode 100644 index 0000000000..895ad521f4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/setuint8/index.html @@ -0,0 +1,84 @@ +--- +title: DataView.prototype.setUint8() +slug: Web/JavaScript/Reference/Global_Objects/DataView/setUint8 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView/setUint8 +--- +
{{JSRef}}
+ +

setUint8()DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(无符号字节).

+ +
{{EmbedInteractiveExample("pages/js/dataview-setuint8.html")}}
+ + + +

语法

+ +
dataview.setUint8(byteOffset, value)
+ +

参数

+ +
+
byteOffset
+
偏移量,从头开始计算,单位为字节
+
value
+
设置的数值
+
+ +

返回

+ +

{{jsxref("undefined")}}.

+ +

抛出错误

+ +
+
{{jsxref("RangeError")}}
+
如果byteOffset超出了视图能储存的值,就会抛出错误.
+
+ +

例子

+ +
var buffer = new ArrayBuffer(8);
+var dataview = new DataView(buffer);
+dataview.setUint8(1, 3);
+dataview.getUint8(1); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-dataview.prototype.setuint8', 'DataView.prototype.setUint8')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-dataview.prototype.setuint8', 'DataView.prototype.setUint8')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.setUint8")}}

+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/@@toprimitive/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/@@toprimitive/index.html new file mode 100644 index 0000000000..5bf2e177ee --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/@@toprimitive/index.html @@ -0,0 +1,61 @@ +--- +title: 'Date.prototype[@@toPrimitive]' +slug: Web/JavaScript/Reference/Global_Objects/Date/@@toPrimitive +translation_of: Web/JavaScript/Reference/Global_Objects/Date/@@toPrimitive +--- +
{{JSRef}}
+ +

[@@toPrimitive]() 方法可以转换一个 Date 对象到一个原始值。

+ +

用法

+ +
Date()[Symbol.toPrimitive](hint);
+
+ +

返回值

+ +

给出的 {{jsxref("Date")}} 的原始值。根据传入参数的不同,可以返回 string 或 number 类型。

+ +

说明

+ +

{{jsxref("Date")}} 对象的 [@@toPrimitive]() 方法可以返回一个原始值,或是 string,或是number。

+ +

如果 hint"string""default"[@@toPrimitive]() 将会调用 {{jsxref("Object.prototype.toString()", "toString")}}。如果 toString 属性不存在,则调用 {{jsxref("Object.prototype.valueOf()", "valueOf")}}。如果 valueOf 也不存在,则抛出一个{{jsxref("TypeError")}}。

+ +

如果 hint"number"[@@toPrimitive]() 会首先尝试 valueOf,若失败再尝试 toString

+ +

当期望一个原始值却收到一个对象时,JavaScript 可以自动的调用 [@@toPrimitive]() 方法来将一个对象转化成原始值,所以你很少会需要自己调用这个方法。

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-date.prototype-@@toprimitive', 'Date.prototype.@@toPrimitive')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-date.prototype-@@toprimitive', 'Date.prototype.@@toPrimitive')}}{{Spec2('ESDraft')}} 
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Date.@@toPrimitive")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/date/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/date/index.html new file mode 100644 index 0000000000..47f7d4bd7d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/date/index.html @@ -0,0 +1,108 @@ +--- +title: Date() constructor +slug: Web/JavaScript/Reference/Global_Objects/Date/Date +translation_of: Web/JavaScript/Reference/Global_Objects/Date/Date +--- +
{{JSRef}}
+ +

Creates a JavaScript Date instance that represents a single moment in time in a platform-independent format. Date objects contain a Number that represents milliseconds since 1 January 1970 UTC.

+ +
{{EmbedInteractiveExample("pages/js/date-constructor.html")}}
+ + + +

Syntax

+ +
new Date()
+new Date(value)
+new Date(dateString)
+new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]])
+
+ +
+

Note: The only correct way to instantiate a new Date object is by using the {{jsxref("new")}} operator. If you simply call the Date object directly, such as now = Date(), the returned value is a string rather than a Date object.

+
+ +

Parameters

+ +

There are four basic forms for the Date() constructor:

+ +
    +
  1. +

    No parameters

    + +

    When no parameters are provided, the newly-created Date object represents the current date and time as of the time of instantiation.

    +
  2. +
  3. +

    Time value or timestamp number

    + +
    +
    value
    +
    An integer value representing the number of milliseconds since January 1, 1970, 00:00:00 UTC (the ECMAScript epoch, equivalent to the UNIX epoch), with leap seconds ignored. Keep in mind that most UNIX Timestamp functions are only accurate to the nearest second.
    +
    +
  4. +
  5. +

    Timestamp string

    + +
    +
    dateString
    +
    A string value representing a date, specified in a format recognized by the {{jsxref("Date.parse()")}} method. (These formats are IETF-compliant RFC 2822 timestamps, and also strings in a version of ISO8601.) +
    +

    Note: Parsing of date strings with the Date constructor (and Date.parse(), which works the same way) is strongly discouraged due to browser differences and inconsistencies.

    + +
      +
    • Support for RFC 2822 format strings is by convention only.
    • +
    • Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local.
    • +
    +
    +
    +
    +
  6. +
  7. +

    Individual date and time component values

    + +

    Given at least a year and month, this form of Date() returns a Date object whose component values (year, month, day, hour, minute, second, and millisecond) all come from the following parameters. Any missing fields are given the lowest possible value (1 for day and 0 for every other component).

    + +
    +
    year
    +
    +

    Integer value representing the year.

    + +

    Values from 0 to 99 map to the years 1900 to 1999. All other values are the actual year. See the example below.

    +
    +
    monthIndex
    +
    Integer value representing the month, beginning with 0 for January to 11 for December.
    +
    day {{optional_inline}}
    +
    Integer value representing the day of the month. The default is 1.
    +
    hours {{optional_inline}}
    +
    Integer value representing the hour of the day. The default is 0 (midnight).
    +
    minutes {{optional_inline}}
    +
    Integer value representing the minute segment of a time. The default is 0 minutes past the hour.
    +
    seconds {{optional_inline}}
    +
    Integer value representing the second segment of a time. The default is 0 seconds past the minute.
    +
    milliseconds {{optional_inline}}
    +
    Integer value representing the millisecond segment of a time. The default is 0 milliseconds past the second.
    +
    +
  8. +
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-date-constructor', 'Date')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Date.Date")}}

diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getdate/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getdate/index.html new file mode 100644 index 0000000000..2c27867870 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getdate/index.html @@ -0,0 +1,78 @@ +--- +title: Date.prototype.getDate() +slug: Web/JavaScript/Reference/Global_Objects/Date/getDate +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getDate +--- +

{{JSRef("Global_Objects", "Date")}}

+ +

根据本地时间,返回一个指定的日期对象为一个月中的哪一日(从1--31)。

+ +
{{EmbedInteractiveExample("pages/js/date-getdate.html")}}
+ + + +

语法

+ +
dateObj.getDate()
+ +

参数

+ +

+ +

描述

+ +

getDate() 返回一个1 到 31的整数值。

+ +

例子

+ +

例子: 使用getDate()方法

+ +

下面第二条语句将值25赋给 day 变量,该值基于日期对象 Xmax95的值。

+ +
var Xmas95 = new Date("December 25, 1995 23:15:00");
+var day = Xmas95.getDate();
+
+alert(day); // 25
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.14', 'Date.prototype.getDate')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getdate', 'Date.prototype.getDate')}}{{Spec2('ES6')}} +

 

+
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.getDate")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getday/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getday/index.html new file mode 100644 index 0000000000..20147639c4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getday/index.html @@ -0,0 +1,88 @@ +--- +title: Date.prototype.getDay() +slug: Web/JavaScript/Reference/Global_Objects/Date/getDay +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getDay +--- +

{{JSRef}}

+ +

getDay() 方法根据本地时间,返回一个具体日期中一周的第几天,0 表示星期天。对于某个月中的第几天,参考{{jsxref("Date.prototype.getDate()")}}.

+ +
{{EmbedInteractiveExample("pages/js/date-getday.html")}}
+ + + +

语法

+ +
dateObj.getDay()
+
+ +

返回值

+ +

根据本地时间,返回一个0到6之间的整数值,代表星期几: 0 代表星期日, 1 代表星期一,2 代表星期二, 依次类推。

+ +

例子

+ +

使用getDay()

+ +

下面第二条语句,基于{{jsxref("Date")}}对象 Xmas95 的值,把 1 赋值给 weekday。也就是说1995年12月25日是星期一。

+ +
var Xmas95 = new Date("December 25, 1995 23:15:30");
+var weekday = Xmas95.getDay();
+
+console.log(weekday); // 1
+ +
+

注意:如果需要,可以使用{{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}与一个额外的options 参数,从而返回这天的全称(如"Monday").使用此方法,结果会更加国际化:

+ +
var options = { weekday: 'long'};
+console.log(new Intl.DateTimeFormat('en-US', options).format(Xmas95));
+// Monday
+console.log(new Intl.DateTimeFormat('de-DE', options).format(Xmas95));
+// Montag
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ESDraft', '#sec-date.prototype.getday', 'Date.prototype.getDay')}}  {{Spec2('ESDraft')}}  
{{SpecName('ES6', '#sec-date.prototype.getday', 'Date.prototype.getDay')}}    {{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-15.9.5.16', 'Date.prototype.getDay')}}        {{Spec2('ES5.1')}}
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.getDay")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getfullyear/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getfullyear/index.html new file mode 100644 index 0000000000..10a0870fac --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getfullyear/index.html @@ -0,0 +1,89 @@ +--- +title: Date.prototype.getFullYear() +slug: Web/JavaScript/Reference/Global_Objects/Date/getFullYear +tags: + - Date + - JavaScript + - Method + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getFullYear +--- +

{{JSRef}}

+ +

getFullYear() 方法根据本地时间返回指定日期的年份。

+ +

此方法替代 {{jsxref("Date.prototype.getYear()", "getYear()")}} 。

+ +
{{EmbedInteractiveExample("pages/js/date-getfullyear.html")}}
+ + + +

语法

+ +
dateObj.getFullYear()
+
+ +

返回值

+ +

根据当地时间,返回一个对应于给定日期的年份数字。

+ +

描述

+ +

getFullYear()返回的值是绝对数。 对于1000到9999之间的日期,getFullYear()返回一个四位数字,如1995。使用此函数确保在2000年后兼容。

+ +

例子

+ +

使用getFullYear()

+ +

下面的例子将当前年份的四位数值分配给变量year

+ +
var today = new Date();
+var year = today.getFullYear();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.10', 'Date.prototype.getFullYear')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getfullyear', 'Date.prototype.getFullYear')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.getfullyear', 'Date.prototype.getFullYear')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.getFullYear")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/gethours/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/gethours/index.html new file mode 100644 index 0000000000..9eb86dc04a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/gethours/index.html @@ -0,0 +1,75 @@ +--- +title: Date.prototype.getHours() +slug: Web/JavaScript/Reference/Global_Objects/Date/getHours +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getHours +--- +

{{JSRef("Global_Objects", "Date")}}

+ +

getHours() 方法根据本地时间,返回一个指定的日期对象的小时。

+ +
{{EmbedInteractiveExample("pages/js/date-gethours.html")}}
+ + + +

语法

+ +
dateObj.getHours()
+ +

参数

+ +

+ +

返回值

+ +

getHours返回一个0 到 23之间的整数值。

+ +

例子

+ +

例子:使用getHours方法

+ +

下面第二条语句,基于日期对象 Xmas95 的值,把 23 赋值给了变量 hours。

+ +
var Xmas95 = new Date("December 25, 1995 23:15:00");
+var hours = Xmas95.getHours();
+
+alert(hours); // 23
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.18', 'Date.prototype.getHours')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.gethours', 'Date.prototype.getHours')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.getHours")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getmilliseconds/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getmilliseconds/index.html new file mode 100644 index 0000000000..5c2b81b6e2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getmilliseconds/index.html @@ -0,0 +1,76 @@ +--- +title: Date.prototype.getMilliseconds() +slug: Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds +--- +

{{JSRef("Global_Objects", "Date")}}

+ +

getMilliseconds() 方法,根据本地时间,返回一个指定的日期对象的毫秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-getmilliseconds.html")}}
+ + + +

语法

+ +
dateObj.getMilliseconds()
+ +

参数

+ +

+ +

描述

+ +

getMilliseconds() 方法返回一个0 到 999的整数。

+ +

例子

+ +

例子:使用getMilliseconds方法

+ +

下例中,将当前时间的毫秒数赋值给变量 ms

+ +
var ms;
+Today = new Date();
+ms = Today.getMilliseconds();
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.3StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.24', 'Date.prototype.getMilliseconds')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getmilliseconds', 'Date.prototype.getMilliseconds')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.getMilliseconds")}}

+ +

相关链接

+ +

 

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getminutes/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getminutes/index.html new file mode 100644 index 0000000000..74ace83ef7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getminutes/index.html @@ -0,0 +1,73 @@ +--- +title: Date.prototype.getMinutes() +slug: Web/JavaScript/Reference/Global_Objects/Date/getMinutes +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getMinutes +--- +

{{JSRef("Global_Objects", "Date")}}

+ +

getMinutes() 方法根据本地时间,返回一个指定的日期对象的分钟数。

+ +
{{EmbedInteractiveExample("pages/js/date-getminutes.html")}}
+ +

语法

+ +
dateObj.getMinutes()
+ +

参数

+ +

+ +

描述

+ +

getMinutes 返回一个0 到 59的整数值。

+ +

例子

+ +

例子:使用getMinutes方法

+ +

下例中,第二行语句运行过后,变量 minutes 的值为15,也就是说 Xmas95 这个日期对象的值为某时15分某秒。

+ +
var Xmas95 = new Date("December 25, 1995 23:15:00");
+var minutes = Xmas95.getMinutes();
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.20', 'Date.prototype.getMinutes')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getminutes', 'Date.prototype.getMinutes')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

 

+ + + +

{{Compat("javascript.builtins.Date.getMinutes")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getmonth/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getmonth/index.html new file mode 100644 index 0000000000..bf2d68f24d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getmonth/index.html @@ -0,0 +1,89 @@ +--- +title: Date.prototype.getMonth() +slug: Web/JavaScript/Reference/Global_Objects/Date/getMonth +tags: + - Date + - JavaScript + - Prototype + - 原型 + - 参考 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getMonth +--- +
{{JSRef}}
+ +

根据本地时间,返回一个指定的日期对象的月份,为基于0的值(0表示一年中的第一月)。

+ +
{{EmbedInteractiveExample("pages/js/date-getmonth.html")}}
+ + + +

语法

+ +
dateObj.getMonth()
+ +

参数

+ +

+ +

返回值

+ +

getMonth返回一个0 到 11的整数值: 0 代表一月份,1 代表二月份, 2 代表三月份,依次类推。

+ +

例子

+ +

使用 getMonth()

+ +

下面第二条语句,基于 {{jsxref("Date")}} 对象 Xmas95 的值,把11赋值给变量 month。

+ +
var Xmas95 = new Date('December 25, 1995 23:15:30');
+var month = Xmas95.getMonth();
+
+console.log(month); // 11
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.9.5.12', 'Date.prototype.getMonth')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getmonth', 'Date.prototype.getMonth')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.getmonth', 'Date.prototype.getMonth')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.getMonth")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getseconds/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getseconds/index.html new file mode 100644 index 0000000000..4edaa5e02c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getseconds/index.html @@ -0,0 +1,77 @@ +--- +title: Date.prototype.getSeconds() +slug: Web/JavaScript/Reference/Global_Objects/Date/getSeconds +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getSeconds +--- +

{{JSRef("Global_Objects", "Date")}}

+ +

getSeconds() 方法根据本地时间,返回一个指定的日期对象的秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-getseconds.html")}}
+ + + +

语法

+ +
dateObj.getSeconds()
+ +

参数

+ +

+ +

描述

+ +

该方法返回一个 0 到 59 的整数值。

+ +

例子

+ +

例子: 使用getSeconds方法

+ +

下面第二条语句,基于日期对象 Xmas95 的值,把 30 赋值给变量 secs

+ +
var Xmas95 = new Date("December 25, 1995 23:15:30");
+var secs = Xmas95.getSeconds();
+ +
 
+ +
 
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.22', 'Date.prototype.getSeconds')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getseconds', 'Date.prototype.getSeconds')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.getSeconds")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/gettime/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/gettime/index.html new file mode 100644 index 0000000000..3bac439efa --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/gettime/index.html @@ -0,0 +1,97 @@ +--- +title: Date.prototype.getTime() +slug: Web/JavaScript/Reference/Global_Objects/Date/getTime +tags: + - Date + - JavaScript + - 原型 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getTime +--- +
{{JSRef}}
+ +

getTime() 方法返回一个时间的格林威治时间数值。

+ +

你可以使用这个方法把一个日期时间赋值给另一个{{jsxref("Date")}} 对象。这个方法的功能和 {{jsxref("Date.valueof", "valueOf()")}} 方法一样。

+ +
{{EmbedInteractiveExample("pages/js/date-gettime.html")}}
+ + + +

语法

+ +
dateObj.getTime() 
+ +

参数

+ +

无。

+ +

返回值

+ +

getTime 方法的返回值一个数值,表示从1970年1月1日0时0分0秒(UTC,即协调世界时)距离该日期对象所代表时间的毫秒数。

+ +

例子

+ +

使用 getTime() 复制日期对象

+ +

创建一个拥有相同时间值的日期对象。

+ +
var birthday = new Date(1991, 9, 17);
+var copy = new Date();
+copy.setTime(birthday.getTime());
+
+ +

测量代码执行时间

+ +

连续调用两个新生成的日期对象的 getTime 方法,根据两次调用的返回值求得时间差。这可以用于计算某些操作的执行时间。避免生成不必要的{{jsxref("Date")}}对象另见{{jsxref("Date.now()")}} 

+ +
var end, start, i;
+
+start = new Date();
+for (i = 0; i < 1000; i++) {
+  Math.sqrt(i);
+}
+end = new Date();
+
+console.log("Operation took " + (end.getTime() - start.getTime()) + " msec");
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态说明
{{SpecName('ES1')}}{{Spec2('ES1')}}初始定义
{{SpecName('ES5.1', '#sec-15.9.5.9', 'Date.prototype.getTime')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.gettime', 'Date.prototype.getTime')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.getTime")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/gettimezoneoffset/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/gettimezoneoffset/index.html new file mode 100644 index 0000000000..3f7ed584aa --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/gettimezoneoffset/index.html @@ -0,0 +1,65 @@ +--- +title: Date.prototype.getTimezoneOffset() +slug: Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

getTimezoneOffset() 方法返回协调世界时(UTC)相对于当前时区的时间差值,单位为分钟。

+ +
{{EmbedInteractiveExample("pages/js/date-gettimezoneoffset.html")}}
+ + + +

语法

+ +
dateObj.getTimezoneOffset()
+ +

参数

+ +

+ +

返回值

+ +

时区偏差(time-zone offset)表示协调世界时(UTC)与本地时区之间的差值,单位为分钟。需要注意的是如果本地时区先于协调世界时,则该差值为正值,如果后于协调世界时则为负值。例如你所在时区为 UTC+10(澳大利亚东部标准时间),将会返回 -600。对于同一个时区,夏令时(Daylight Saving Time)将会改变这个值。

+ +

例子

+ +

例子: 使用getTimezoneOffset方法

+ +
var x = new Date();
+var currentTimeZoneOffsetInHours = x.getTimezoneOffset() / 60;
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.26', 'Date.prototype.getTimezoneOffset')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-date.prototype.gettimezoneoffset', 'Date.prototype.getTimezoneOffset')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.getTimezoneOffset")}}

diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getutcdate/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getutcdate/index.html new file mode 100644 index 0000000000..c39ec91325 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getutcdate/index.html @@ -0,0 +1,75 @@ +--- +title: Date.prototype.getUTCDate() +slug: Web/JavaScript/Reference/Global_Objects/Date/getUTCDate +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getUTCDate +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

getUTCDate() 方法以世界时为标准,返回一个指定的日期对象为一个月中的第几天

+ +
{{EmbedInteractiveExample("pages/js/date-getutcdate.html")}}
+ +

语法

+ +
dateObj.getUTCDate()
+ +

参数

+ +

+ +

返回值

+ +

getUTCDate() 返回一个 1 到 31 的整数值

+ +

例子

+ +

例子: 使用 getUTCDate() 方法

+ +

下面的例子是把当前日期的天数部分赋值给变量 day.

+ +
var today = new Date();
+var day = today.getUTCDate();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.15', 'Date.prototype.getUTCDate')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getutcdate', 'Date.prototype.getUTCDate')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.getUTCDate")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getutcday/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getutcday/index.html new file mode 100644 index 0000000000..82acb18189 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getutcday/index.html @@ -0,0 +1,77 @@ +--- +title: Date.prototype.getUTCDay() +slug: Web/JavaScript/Reference/Global_Objects/Date/getUTCDay +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getUTCDay +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

getUTCDay() 方法以世界时为标准,返回一个指定的日期对象为一星期中的第几天,其中 0 代表星期天。

+ +
{{EmbedInteractiveExample("pages/js/date-getutcday.html")}}
+ + + +

语法

+ +
dateObj.getUTCDay()
+ +

参数

+ +

无。

+ +

返回值

+ +

getUTCDay() 方法返回一个对应一星期中第几天的整数:0 代表星期天,1 代表星期一,2 代表星期二,依次类推。

+ +

例子

+ +

例子: 使用 getUTCDay() 方法

+ +

下面的例子是把当前日期的星期部分赋值给变量 weekday

+ +
var today = new Date();
+var weekday = today.getUTCDay();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.17', 'Date.prototype.getUTCDay')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getutcday', 'Date.prototype.getUTCDay')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.getUTCDay")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getutcfullyear/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getutcfullyear/index.html new file mode 100644 index 0000000000..8f19fa4845 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getutcfullyear/index.html @@ -0,0 +1,76 @@ +--- +title: Date.prototype.getUTCFullYear() +slug: Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

getUTCFullYear() 以世界时为标准,返回一个指定的日期对象的年份。

+ +
{{EmbedInteractiveExample("pages/js/date-getutcfullyear.html")}}
+ + + +

语法

+ +
dateObj.getUTCFullYear()
+ +

参数

+ +

无。

+ +

返回值

+ +

getUTCFullYear() 返回一个绝对数值,符合 Year-2000 标准,例如 1995。

+ +

例子

+ +

例子: 使用 getUTCFullYear() 方法

+ +

下面的例子是把当前年份的四位数值复制给变量 year

+ +
var today = new Date();
+var year = today.getUTCFullYear();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.11', 'Date.prototype.getUTCFullYear')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getutcfullyear', 'Date.prototype.getUTCFullYear')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.getUTCFullYear")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getutchours/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getutchours/index.html new file mode 100644 index 0000000000..85c105c875 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getutchours/index.html @@ -0,0 +1,76 @@ +--- +title: Date.prototype.getUTCHours() +slug: Web/JavaScript/Reference/Global_Objects/Date/getUTCHours +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getUTCHours +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

getUTCHours() 方法以世界时为标准,返回一个指定的日期对象的小时数。

+ +
{{EmbedInteractiveExample("pages/js/date-getutchours.html")}}
+ + + +

语法

+ +
dateObj.getUTCHours()
+ +

参数

+ +

无。

+ +

返回值

+ +

getUTCHours() 返回一个 0 到 23 的整数。

+ +

例子

+ +

例子: 使用 getUTCHours() 方法

+ +

下例将当前时间的小时部分赋值给变量 hours

+ +
var today = new Date();
+var hours = today.getUTCHours();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.19', 'Date.prototype.getUTCHours')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getutchours', 'Date.prototype.getUTCHours')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.getUTCHours")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getutcmilliseconds/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getutcmilliseconds/index.html new file mode 100644 index 0000000000..a77a980836 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getutcmilliseconds/index.html @@ -0,0 +1,74 @@ +--- +title: Date.prototype.getUTCMilliseconds() +slug: Web/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

getUTCMilliseconds() 方法以世界时为标准,返回一个指定的日期对象的毫秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-getutcmilliseconds.html")}}
+ +

语法

+ +
dateObj.getUTCMilliseconds()
+ +

参数

+ +

无。

+ +

返回值

+ +

getUTCMilliseconds() 返回一个 0 到 999 的整数。

+ +

例子

+ +

例子: 使用 getUTCMilliseconds() 方法

+ +

下例将当前时间的毫秒部分赋值给变量 milliseconds

+ +
var today = new Date();
+var milliseconds = today.getUTCMilliseconds();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.25', 'Date.prototype.getUTCMilliseconds')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getutcmilliseconds', 'Date.prototype.getUTCMilliseconds')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.getUTCMilliseconds")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getutcminutes/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getutcminutes/index.html new file mode 100644 index 0000000000..f4df8aff72 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getutcminutes/index.html @@ -0,0 +1,74 @@ +--- +title: Date.prototype.getUTCMinutes() +slug: Web/JavaScript/Reference/Global_Objects/Date/getUTCMinutes +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getUTCMinutes +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

getUTCMinutes() 方法以世界时为标准,返回一个指定的日期对象的分钟数。

+ +
{{EmbedInteractiveExample("pages/js/date-getutcminutes.html")}}
+ +

语法

+ +
dateObj.getUTCMinutes()
+ +

参数

+ +

无。

+ +

返回值

+ +

getUTCMinutes() 返回一个 0 到 59 的整数。

+ +

例子

+ +

例子: 使用 getUTCMinutes() 方法

+ +

下例将当前时间的分钟部分赋值给变量 minutes

+ +
var today = new Date();
+var minutes = today.getUTCMinutes();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.21', 'Date.prototype.getUTCMinutes')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getutcminutes', 'Date.prototype.getUTCMinutes')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.getUTCMinutes")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getutcmonth/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getutcmonth/index.html new file mode 100644 index 0000000000..015b513a72 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getutcmonth/index.html @@ -0,0 +1,76 @@ +--- +title: Date.prototype.getUTCMonth() +slug: Web/JavaScript/Reference/Global_Objects/Date/getUTCMonth +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getUTCMonth +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

getUTCMonth() 方法以世界时为标准,返回一个指定的日期对象的月份,它是从 0 开始计数的(0 代表一年的第一个月)。

+ +
{{EmbedInteractiveExample("pages/js/date-getutcmonth.html")}}
+ + + +

语法

+ +
dateObj.getUTCMonth()
+ +

参数

+ +

无。

+ +

返回值

+ +

getUTCMonth() 返回一个 0 到 11 的整数,分别对应以下月份:0 代表一月,1 代表二月,2 代表三月,依次类推。

+ +

例子

+ +

例子: 使用 getUTCMonth() 方法

+ +

下例将当前时间的月份赋值给变量 month

+ +
var today = new Date();
+var month = today.getUTCMonth();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.13', 'Date.prototype.getUTCMonth')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getutcmonth', 'Date.prototype.getUTCMonth')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.getUTCMonth")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getutcseconds/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getutcseconds/index.html new file mode 100644 index 0000000000..84f2e82ff3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getutcseconds/index.html @@ -0,0 +1,74 @@ +--- +title: Date.prototype.getUTCSeconds() +slug: Web/JavaScript/Reference/Global_Objects/Date/getUTCSeconds +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getUTCSeconds +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

getUTCSeconds() 方法以世界时为标准,返回一个指定的日期对象的秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-getutcseconds.html")}}
+ +

语法

+ +
dateObj.getUTCSeconds()
+ +

参数

+ +

无。

+ +

返回值

+ +

getUTCSeconds() 返回一个 0 到 59 的整数。

+ +

例子

+ +

例子: 使用 getUTCSeconds() 方法

+ +

下例将当前时间的秒数部分赋值给变量 seconds

+ +
var today = new Date();
+var seconds = today.getUTCSeconds();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.23', 'Date.prototype.getUTCSeconds')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.getutcseconds', 'Date.prototype.getUTCSeconds')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.getUTCSeconds")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/getyear/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/getyear/index.html new file mode 100644 index 0000000000..29f69b85d5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/getyear/index.html @@ -0,0 +1,114 @@ +--- +title: Date.prototype.getYear() +slug: Web/JavaScript/Reference/Global_Objects/Date/getYear +translation_of: Web/JavaScript/Reference/Global_Objects/Date/getYear +--- +
{{JSRef("Global_Objects", "Date")}} {{Deprecated_header("")}}
+ +

getYear() 方法返回指定的本地日期的年份。因为 getYear 不返回千禧年[full years] ("year 2000 problem"),所以这个方法不再被使用,现在替换为 {{jsxref("Date.getFullYear", "getFullYear")}} .

+ +

Syntax

+ +
dateObj.getYear() 
+ +

Parameters

+ +

None.

+ +

Returns

+ +

The getYear method returns the year minus 1900; thus:

+ + + +

To take into account years before and after 2000, you should use {{jsxref("Date.getFullYear", "getFullYear()")}} instead of getYear so that the year is specified in full.

+ +

Backward Compatibility

+ +

Behaviour in JavaScript 1.2 and earlier

+ +

The getYear method returns either a 2-digit or 4-digit year:

+ + + +

Examples

+ +

Example: Years between 1900 and 1999

+ +

The second statement assigns the value 95 to the variable year.

+ +
var Xmas = new Date("December 25, 1995 23:15:00");
+var year = Xmas.getYear(); // returns 95
+
+ +

Example: Years above 1999

+ +

The second statement assigns the value 100 to the variable year.

+ +
var Xmas = new Date("December 25, 2000 23:15:00");
+var year = Xmas.getYear(); // returns 100
+
+ +

Example: Years below 1900

+ +

The second statement assigns the value -100 to the variable year.

+ +
var Xmas = new Date("December 25, 1800 23:15:00");
+var year = Xmas.getYear(); // returns -100
+
+ +

Example: Setting and getting a year between 1900 and 1999

+ +

The second statement assigns the value 95 to the variable year, representing the year 1995.

+ +
var Xmas.setYear(95);
+var year = Xmas.getYear(); // returns 95
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-B.2.4', 'Date.prototype.getYear')}}{{Spec2('ES5.1')}}Defined in the (informative) compatibility annex.
{{SpecName('ES6', '#sec-date.prototype.getyear', 'Date.prototype.getYear')}}{{Spec2('ES6')}}Defined in the (normative) annex for additional features for web browsers.
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Date.getYear")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/index.html new file mode 100644 index 0000000000..9cacee3238 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/index.html @@ -0,0 +1,248 @@ +--- +title: Date +slug: Web/JavaScript/Reference/Global_Objects/Date +tags: + - Date + - JavaScript + - 日期 + - 时间 +translation_of: Web/JavaScript/Reference/Global_Objects/Date +--- +

{{JSRef}}

+ +

创建一个 JavaScript Date 实例,该实例呈现时间中的某个时刻。Date 对象则基于 Unix Time Stamp,即自1970年1月1日(UTC)起经过的毫秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-constructor.html")}}
+ + + +

语法

+ +
new Date();
+new Date(value);
+new Date(dateString);
+new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
+ +
+

创建一个新Date对象的唯一方法是通过{{jsxref("Operators/new", "new")}} 操作符,例如:let now = new Date();
+ 若将它作为常规函数调用(即不加 {{jsxref("Operators/new", "new")}} 操作符),将返回一个字符串,而非 Date 对象。 

+
+ +

参数

+ +

Date()构造函数有四种基本形式

+ +

没有参数

+ +

如果没有提供参数,那么新创建的Date对象表示实例化时刻的日期和时间。

+ +

Unix时间戳

+ +
+
value
+
一个 Unix 时间戳(Unix Time Stamp),它是一个整数值,表示自1970年1月1日00:00:00 UTC(the Unix epoch)以来的毫秒数,忽略了闰秒。请注意大多数 Unix 时间戳功能仅精确到最接近的秒。
+
+

时间戳字符串

+
+
dateString
+
表示日期的字符串值。该字符串应该能被 {{jsxref("Date.parse()")}} 正确方法识别(即符合 IETF-compliant RFC 2822 timestamps 或 version of ISO8601)。 +
+

注意: 由于浏览器之间的差异与不一致性,强烈不推荐使用Date构造函数来解析日期字符串 (或使用与其等价的Date.parse)。对 RFC 2822 格式的日期仅有约定俗称的支持。 对 ISO 8601 格式的支持中,仅有日期的串 (例如 "1970-01-01") 会被处理为 UTC 而不是本地时间,与其他格式的串的处理不同。

+
+
+
+ +

分别提供日期与时间的每一个成员

+ +

当至少提供了年份与月份时,这一形式的 Date() 返回的 Date 对象中的每一个成员都来自下列参数。没有提供的成员将使用最小可能值(对日期为1,其他为0)。

+ +
+
year
+
表示年份的整数值。 0到99会被映射至1900年至1999年,其它值代表实际年份。参见 {{anch("Two_digit_years_map_to_1900_-_1999", "示例")}}。
+
monthIndex
+
表示月份的整数值,从 0(1月)到 11(12月)。
+
date{{optional_inline}}
+
表示一个月中的第几天的整数值,从1开始。默认值为1。
+
hours {{optional_inline}}
+
表示一天中的小时数的整数值 (24小时制)。默认值为0(午夜)。
+
minutes {{optional_inline}}
+
表示一个完整时间(如 01:10:00)中的分钟部分的整数值。默认值为0。
+
seconds {{optional_inline}}
+
表示一个完整时间(如 01:10:00)中的秒部分的整数值。默认值为0。
+
milliseconds {{optional_inline}}
+
表示一个完整时间的毫秒部分的整数值。默认值为0。
+
+ +

使用注释

+ +
+

注意 参数monthIndex 是从“0”开始计算的,这就意味着一月份为“0”,十二月份为“11”。

+
+ +
+

注意:当Date作为构造函数调用并传入多个参数时,如果数值大于合理范围时(如月份为 13 或者分钟数为 70),相邻的数值会被调整。比如 new Date(2013, 13, 1)等于new Date(2014, 1, 1),它们都表示日期2014-02-01(注意月份是从0开始的)。其他数值也是类似,new Date(2013, 2, 1, 0, 70)等于new Date(2013, 2, 1, 1, 10),都表示同一个时间:2013-03-01T01:10:00

+
+ +
+

注意:当Date作为构造函数调用并传入多个参数时,所定义参数代表的是当地时间。如果需要使用世界协调时 UTC,使用 new Date({{jsxref("Date.UTC()", "Date.UTC(...)")}}) 和相同参数。

+
+ +

简介

+ + + +

属性

+ +
+
{{jsxref("Date.prototype")}}
+
允许为 Date 对象添加属性。
+
Date.length
+
Date.length 的值是 7。这是该构造函数可接受的参数个数。
+
+ +

方法

+ +
+
{{jsxref("Date.now()")}}
+
返回自 1970-1-1 00:00:00  UTC(世界标准时间)至今所经过的毫秒数。
+
{{jsxref("Date.parse()")}}
+
解析一个表示日期的字符串,并返回从 1970-1-1 00:00:00 所经过的毫秒数。 +
+

注意: 由于浏览器差异和不一致,强烈建议不要使用Date.parse解析字符串。

+
+
+
{{jsxref("Date.UTC()")}}
+
接受和构造函数最长形式的参数相同的参数(从2到7),并返回从 1970-01-01 00:00:00 UTC 开始所经过的毫秒数。
+
+ +

JavaScript Date 实例

+ +

所有的 Date 实例都继承自 {{jsxref("Date.prototype")}}。修改 Date 构造函数的原型对象会影响到所有的 Date 实例。

+ +

实例属性

+ +
+
Date.prototype.constructor
+
返回创建了实例的构造函数,默认是 {{jsxref("Date")}} 构造函数。
+
+ +

实例方法

+ +

{{ page("/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/prototype", "Methods") }}

+ +

例子

+ +

>例子:创建一个日期对象的几种方法

+ +

下例展示了用来创建一个日期对象的多种方法。

+ +
+

注意: 由于浏览器差异和不一致性,强烈建议不要使用Date构造函数(和Date.parse,它们是等效的)解析日期字符串。

+
+ +
var today = new Date();
+var birthday = new Date('December 17, 1995 03:24:00');
+var birthday = new Date('1995-12-17T03:24:00');
+var birthday = new Date(1995, 11, 17);
+var birthday = new Date(1995, 11, 17, 3, 24, 0);
+
+ +

例子:将两位数年份映射为 1900 - 1999 年

+ +

为了创建和获取 0 到 99 之间的年份,应使用 {{jsxref("Date.prototype.setFullYear()")}} 和 {{jsxref("Date.prototype.getFullYear()")}} 方法。

+ +
var date = new Date(98, 1); // Sun Feb 01 1998 00:00:00 GMT+0000 (GMT)
+
+// 已弃用的方法, 同样将 98 映射为 1998
+date.setYear(98);           // Sun Feb 01 1998 00:00:00 GMT+0000 (GMT)
+
+date.setFullYear(98);       // Sat Feb 01 0098 00:00:00 GMT+0000 (BST)
+
+ +

例子:计算经过的时间

+ +

下例展示了如何以毫秒精度计算两个日期对象的时间差:

+ +

由于不同日期、月份、年份长度的不同(日期长度不同来自夏令时的切换),使用大于秒、分钟、小时的单位表示经过的时间会遇到很多问题,在使用前需要经过详尽的调研。

+ +
// 使用 Date 对象
+var start = Date.now();
+
+// 调用一个消耗一定时间的方法:
+doSomethingForALongTime();
+var end = Date.now();
+var elapsed = end - start; // 以毫秒计的运行时长
+ +
// 使用内建的创建方法
+var start = new Date();
+
+// 调用一个消耗一定时间的方法:
+doSomethingForALongTime();
+var end = new Date();
+var elapsed = end.getTime() - start.getTime(); // 运行时间的毫秒值
+ +
// to test a function and get back its return
+function printElapsedTime (fTest) {
+    var nStartTime = Date.now(),
+        vReturn = fTest(),
+        nEndTime = Date.now();
+    alert("Elapsed time: " + String(nEndTime - nStartTime) + " milliseconds");
+    return vReturn;
+}
+yourFunctionReturn = printElapsedTime(yourFunction);
+
+ +
+

注意:在支持 {{domxref("window.performance", "Web Performance API")}} 的高精细度(high-resolution)时间功能的浏览器中,{{domxref("Performance.now()")}} 提供的所经过的时间比 {{jsxref("Date.now()")}} 更加可靠、精确。

+
+ +

获取自 Unix 起始时间以来经过的秒数

+ +
var seconds = Math.floor(Date.now() / 1000);
+ +

注意此处需要返回一个整数 (仅做除法得到的不是整数),并且需要返回实际已经经过的秒数(所以这里使用了{{jsxref("Math.floor()")}}而不是{{jsxref("Math.round()")}}).

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ESDraft', '#sec-date-objects', 'Date')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-date-objects', 'Date')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-15.9', 'Date')}}{{Spec2('ES5.1')}}
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date")}}

diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/now/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/now/index.html new file mode 100644 index 0000000000..317ecc8b69 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/now/index.html @@ -0,0 +1,101 @@ +--- +title: Date.now() +slug: Web/JavaScript/Reference/Global_Objects/Date/now +tags: + - Date + - JavaScript + - Method + - polyfill + - 参考 + - 方法 + - 时间 +translation_of: Web/JavaScript/Reference/Global_Objects/Date/now +--- +
{{JSRef}}
+ +

Date.now() 方法返回自 1970 年 1 月 1 日 00:00:00 (UTC) 到当前时间的毫秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-now.html")}}
+ +

语法

+ +
var timeInMs = Date.now();
+
+ +

返回值

+ +

一个 {{jsxref("Number")}},表示自 UNIX 纪元开始(1970 年 1 月 1 日 00:00:00 (UTC))到当前时间的毫秒数。

+ +

描述

+ +

因为 now() 是 {{jsxref("Date")}} 的一个静态函数,所以必须以 Date.now() 的形式来使用。

+ +

时间精度被降低

+ +

为了提供针对定时攻击和指纹追踪的保护,Date.now() 的精度可能会根据浏览器的高级设置项目而被取整。
+ 在 Firefox 中,默认启用 privacy.reduceTimerPrecision 设置项,在 Firefox 59 中,默认被取整至 20 微秒;在 Firefox 60 中,则被取整至 2 毫秒。

+ +
// reduced time precision (2ms) in Firefox 60
+Date.now()
+// 1519211809934
+// 1519211810362
+// 1519211811670
+// ...
+
+
+// reduced time precision with `privacy.resistFingerprinting` enabled
+Date.now();
+// 1519129853500
+// 1519129858900
+// 1519129864400
+// ...
+
+ +

在 Firefox 中,还可以通过启用 privacy.resistFingerprinting 来进一步降低精度。启用后,精度将为 100 毫秒或者 privacy.resistFingerprinting.reduceTimerPrecision.microseconds 的值,取决于这两个值中哪一个更大,也就是,精度更低一些。

+ +

Polyfill

+ +

该方法在 ECMA-262 第五版中被标准化,可以通过下面的代码端来兼容那些不支持该方法的引擎:

+ +
if (!Date.now) {
+  Date.now = function now() {
+    return new Date().getTime();
+  };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范版本规范状态说明
{{SpecName('ES5.1', '#sec-15.9.4.4', 'Date.now')}}{{Spec2('ES5.1')}}初始定义。在 JavaScript 1.5 中实现
{{SpecName('ES6', '#sec-date.now', 'Date.now')}}{{Spec2('ES6')}} 
+  
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.now")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/parse/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/parse/index.html new file mode 100644 index 0000000000..701f6fc103 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/parse/index.html @@ -0,0 +1,184 @@ +--- +title: Date.parse() +slug: Web/JavaScript/Reference/Global_Objects/Date/parse +tags: + - Date + - JavaScript + - Method + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Date/parse +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

Date.parse() 方法解析一个表示某个日期的字符串,并返回从1970-1-1 00:00:00 UTC 到该日期对象(该日期对象的UTC时间)的毫秒数,如果该字符串无法识别,或者一些情况下,包含了不合法的日期数值(如:2015-02-31),则返回值为NaN。

+ +

不推荐在ES5之前使用Date.parse方法,因为字符串的解析完全取决于实现。直到至今,不同宿主在如何解析日期字符串上仍存在许多差异,因此最好还是手动解析日期字符串(在需要适应不同格式时库能起到很大帮助)。    

+ +
{{EmbedInteractiveExample("pages/js/date-parse.html")}}
+ + + +

语法

+ +

显式调用:

+ +
Date.parse(dateString)
+ +

隐式调用:

+ +
new Date(dateString).getTime()
+
+ +

参数

+ +
+
dateString
+
一个符合 RFC2822 或 ISO 8601 日期格式的字符串(其他格式也许也支持,但结果可能与预期不符)。
+
+ +

返回值

+ +
+
一个表示从1970-1-1 00:00:00 UTC到给定日期字符串所表示时间的毫秒数的数值。如果参数不能解析为一个有效的日期,则返回{{jsxref("NaN")}}。
+
+ +

描述

+ +

parse 方法接受一个日期字符串(例如 "Dec 25, 1995"),并返回从1970-1-1 00:00:00 UTC到该日期字符串所表示日期的毫秒数。该方法在基于字符串值设置日期值时很有用,例如结合使用{{jsxref("Global_Objects/Date/setTime", "setTime()")}} 方法和 {{jsxref("Global_Objects/Date", "Date()")}} 构造函数。

+ +

parse 方法接受一个表示时间的字符串,返回相应的时间值。该方法可以接受符合 RFC2822 / IETF 日期语法 (RFC2822 Section 3.3) 的字符串,如 "Mon, 25 Dec 1995 13:30:00 GMT"。该方法能够理解美国大陆时区的缩写,但是为了更通用,应该使用时区偏移,如 "Mon, 25 Dec 1995 13:30:00 +0430" (格林威治的子午线向东偏移4小时30分钟)。如果没有指定时区,默认使用本地时区。

+ +

GMT 和 UTC 被看作相等。 如果 RFC2822 Section 3.3 格式中不包含时区信息时,会以本地时区来解析日期字符串。

+ +

由于在解析日期字符串时存在偏差会导致结果不一致,因此推荐始终手动解析日期字符串,特别是不同的ECMAScript实现会把诸如“2015-10-12 12:00:00”的字符串解析为NaN,UTC或者本地时间。

+ +

ECMAScript 5 ISO-8601 日期格式支持

+ +

另外,日期时间字符串也可以使用 ISO 8601 格式。例如,"2011-10-10" (仅日期)或 "2011-10-10T14:48:00" (日期和时间)能够作为参数被传递和解析。 如果参数字符串只包含日期格式,那么将会使用UTC时区来解析该参数。而如果是ISO 8601 格式中规定的时间加日期的格式,则将会被作为本地时区处理。

+ +

虽然在日期字符串解析过程中会使用时区修饰符,但返回值总会是从由NaN表示的1970-1-1 00:00:00 UTC到该日期字符串所表示日期的毫秒数。

+ +

由于 parse() 是 {{jsxref("Date")}} 的一个静态方法 , 所以应该使用 Date.parse() 来调用,而不是作为 {{jsxref("Date")}} 的实例方法。

+ +

默认时区的区别

+ +

当输入为 "March 7, 2014" 时, parse()  将默认使用本地时区。但如果使用 ISO  格式如 "2014-03-07" ,则会被默认为 UTC (ES5 和 ECMAScript 2015) 时区。  因此除非系统本地时区为 UTC,由这些字符串解析出的 {{jsxref("Date")}}  对象可能会因为 ECMAScript  版本不同而代表不同的时间。这意味着两个看起来等效的字符串可能因为它们的格式不同而被转换成不同的值。

+ +

引擎相关的日期格式

+ +

ECMAScript  规范规定:如果一个字符串不符合标准格式,则函数可以使用任何由引擎决定的策略或解析算法。 Date.parse()  对于因包含有无效元素而无法识别的 ISO 格式字符串或者日期应该返回 {{jsxref("NaN")}} 。

+ +

但是, 在如 ECMA-262 规范中定义的情况,如果因为无效值而导致日期字符串不能被识别为 ISO 格式时,根据浏览器和给定的值不同,返回值可以是,也可以不是 {{jsxref("NaN")}} 。比如:

+ +
// 包含无效值的非 ISO 格式字符串
+new Date('23/25/2014');
+ +

在 Firefox 30 中会被识别为本地时区的2015年12月25日,而在 Safari 7 中则是无效日期。但是,如果字符串被识别为 ISO 格式并且包含无效值,则在所有遵循 ES5 或者更新标准的浏览器中都会返回 {{jsxref("NaN")}} 。

+ +
// 包含无效值的 ISO 格式字符串
+new Date('2014-25-23').toISOString();
+// 在所有遵循 ES5的浏览器中返回 "RangeError: invalid date"
+ +

SpiderMonkey 的引擎策略可以在 jsdate.cpp  中找到。字符串 "10 06 2014"  可以作为非 ISO 格式字符串使用自定义处理方式的例子。参见这篇关于解析如何进行的粗略纲要

+ +
new Date('10 06 2014');
+ +

将会被解析为本地时间 2014年10月6日,而不是6月10日。另一个例子

+ +
new Date('foo-bar 2014').toString();
+// 返回: "Invalid Date"
+
+Date.parse('foo-bar 2014');
+// 返回: NaN
+ +

例子

+ +

例子:使用 Date.parse()

+ +

如果 IPOdate 是一个已经存在的 {{jsxref("Date")}} 对象,则可以把其设置为本地时间 1995年8月9日。如下:

+ +
IPOdate.setTime(Date.parse('Aug 9, 1995'));
+ +

其他一些解析非标准格式日期的例子:

+ +
Date.parse("Aug 9, 1995");
+
+ +

在时区 GMT-0300 中返回 807937200000 ,在其他时区中返回另外的值,因为未指定时区并且不是 ISO 格式,所以默认使用本地时区。

+ +
Date.parse("Wed, 09 Aug 1995 00:00:00 GMT");
+
+ +

因为指定了时区 GMT (UTC),所以不管本地时区如何,总是返回 807926400000

+ +
Date.parse("Wed, 09 Aug 1995 00:00:00");
+
+ +

在时区 GMT-0300 中返回 807937200000 ,在其他时区中返回另外的值,因为没有时区标志并且不是 ISO 格式,所以作为本地时区处理。

+ +
Date.parse("Thu, 01 Jan 1970 00:00:00 GMT");
+
+ +

因为指定了时区 GMT (UTC),所以不管本地时区如何,总是返回 0

+ +
Date.parse("Thu, 01 Jan 1970 00:00:00");
+
+ +

在时区 GMT-0400 中返回 14400000,在其他时区中返回另外的值,因为未指定时区并且不是 ISO 格式,所以使用本地时区处理。

+ +
Date.parse("Thu, 01 Jan 1970 00:00:00 GMT-0400");
+
+ +

因为指定了时区 GMT (UTC),所以不管本地时区如何,总是返回 14400000

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.4.2', 'Date.parse')}}{{Spec2('ES5.1')}}ISO 8601 format added
{{SpecName('ES6', '#sec-date.parse', 'Date.parse')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.parse', 'Date.parse')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

 

+ + + +

{{Compat("javascript.builtins.Date.parse")}}

+ +

兼容性提示

+ +

Firefox 49 {{geckoRelease(49)}} 修改了解析2位数年份的方式,从和 Internet Explorer 一致改为和 Google Chrome  浏览器一致。现在,2位数的年份小于等于 50  的将会被解析为21世纪的年份。比如, 04/16/17 ,在之前会被解析为 1917年4月16日,现在将被解析为 2017年4月16日。为了避免任何可能的同步问题或者有歧义的年份,推荐使用 ISO 8601 格式如 "2017-04-16" ({{bug(1265136)}})。

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/prototype/index.html new file mode 100644 index 0000000000..198a479453 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/prototype/index.html @@ -0,0 +1,180 @@ +--- +title: Date.prototype +slug: Web/JavaScript/Reference/Global_Objects/Date/prototype +tags: + - Date + - JavaScript + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Date +--- +
{{JSRef}}
+ +

Date.prototype 属性表示{{jsxref("Date")}}构造函数的原型。

+ +
{{js_property_attributes(0,0,1)}}
+ +

描述

+ +

{{jsxref("Date")}}实例继承自Date.prototype。可以通过修改构造函数的原型对象来影响 {{jsxref("Date")}}实例继承的属性和方法。

+ +

为了兼容千禧年计算(也即考虑到 2000 年),应该总是指定完整的年份,例如,使用 1998,而不是 98。为了方便以完整的格式指定年份, JavaScript 包含了相应的方法{{jsxref("Global_Objects/Date/getFullYear", "getFullYear()")}},{{jsxref("Global_Objects/Date/setFullYear", "setFullYear()")}}, {{jsxref("Global_Objects/Date/getUTCFullYear", "getUTCFullYear()")}} 和{{jsxref("Global_Objects/Date/setUTCFullYear", "setUTCFullYear()")}}。

+ +

从 ECMAScript 6 开始,Date.prototype本身就是一个普通的对象。不是{{jsxref("Date")}}的实例。

+ +

属性

+ +
+
Date.prototype.constructor
+
返回创建该实例的函数。默认是Date构造函数。
+
+ +

方法

+ +

Getter

+ +
+
{{jsxref("Date.prototype.getDate()")}}
+
根据本地时间返回指定日期对象的月份中的第几天(1-31)。
+
{{jsxref("Date.prototype.getDay()")}}
+
根据本地时间返回指定日期对象的星期中的第几天(0-6)。
+
{{jsxref("Date.prototype.getFullYear()")}}
+
根据本地时间返回指定日期对象的年份(四位数年份时返回四位数字)。
+
{{jsxref("Date.prototype.getHours()")}}
+
根据本地时间返回指定日期对象的小时(0-23)。
+
{{jsxref("Date.prototype.getMilliseconds()")}}
+
根据本地时间返回指定日期对象的毫秒(0-999)。
+
{{jsxref("Date.prototype.getMinutes()")}}
+
根据本地时间返回指定日期对象的分钟(0-59)。
+
{{jsxref("Date.prototype.getMonth()")}}
+
根据本地时间返回指定日期对象的月份(0-11)。
+
{{jsxref("Date.prototype.getSeconds()")}}
+
根据本地时间返回指定日期对象的秒数(0-59)。
+
{{jsxref("Date.prototype.getTime()")}}
+
返回从1970-1-1 00:00:00 UTC(协调世界时)到该日期经过的毫秒数,对于1970-1-1 00:00:00 UTC之前的时间返回负值。
+
{{jsxref("Date.prototype.getTimezoneOffset()")}}
+
返回当前时区的时区偏移。
+
{{jsxref("Date.prototype.getUTCDate()")}}
+
根据世界时返回特定日期对象一个月的第几天(1-31).
+
{{jsxref("Date.prototype.getUTCDay()")}}
+
根据世界时返回特定日期对象一个星期的第几天(0-6).
+
{{jsxref("Date.prototype.getUTCFullYear()")}}
+
根据世界时返回特定日期对象所在的年份(4位数).
+
{{jsxref("Date.prototype.getUTCHours()")}}
+
根据世界时返回特定日期对象当前的小时(0-23).
+
{{jsxref("Date.prototype.getUTCMilliseconds()")}}
+
根据世界时返回特定日期对象的毫秒数(0-999).
+
{{jsxref("Date.prototype.getUTCMinutes()")}}
+
根据世界时返回特定日期对象的分钟数(0-59).
+
{{jsxref("Date.prototype.getUTCMonth()")}}
+
根据世界时返回特定日期对象的月份(0-11).
+
{{jsxref("Date.prototype.getUTCSeconds()")}}
+
根据世界时返回特定日期对象的秒数(0-59).
+
{{jsxref("Date.prototype.getYear()")}}{{deprecated_inline}}
+
根据特定日期返回年份 (通常 2-3 位数). 使用 {{jsxref("Global_Objects/Date/getFullYear", "getFullYear()")}} .
+
+ +

Setter

+ +
+
{{jsxref("Date.prototype.setDate()")}}
+
根据本地时间为指定的日期对象设置月份中的第几天。
+
{{jsxref("Date.prototype.setFullYear()")}}
+
根据本地时间为指定日期对象设置完整年份(四位数年份是四个数字)。
+
{{jsxref("Date.prototype.setHours()")}}
+
根据本地时间为指定日期对象设置小时数。
+
{{jsxref("Date.prototype.setMilliseconds()")}}
+
根据本地时间为指定日期对象设置毫秒数。
+
{{jsxref("Date.prototype.setMinutes()")}}
+
根据本地时间为指定日期对象设置分钟数。
+
{{jsxref("Date.prototype.setMonth()")}}
+
根据本地时间为指定日期对象设置月份。
+
{{jsxref("Date.prototype.setSeconds()")}}
+
根据本地时间为指定日期对象设置秒数。
+
{{jsxref("Date.prototype.setTime()")}}
+
通过指定从 1970-1-1 00:00:00 UTC 开始经过的毫秒数来设置日期对象的时间,对于早于 1970-1-1 00:00:00 UTC的时间可使用负值。
+
{{jsxref("Date.prototype.setUTCDate()")}}
+
根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。
+
{{jsxref("Date.prototype.setUTCFullYear()")}}
+
根据世界时设置 Date 对象中的年份(四位数字)。
+
{{jsxref("Date.prototype.setUTCHours()")}}
+
根据世界时设置 Date 对象中的小时 (0 ~ 23)。
+
{{jsxref("Date.prototype.setUTCMilliseconds()")}}
+
根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。
+
{{jsxref("Date.prototype.setUTCMinutes()")}}
+
根据世界时设置 Date 对象中的分钟 (0 ~ 59)。
+
{{jsxref("Date.prototype.setUTCMonth()")}}
+
根据世界时设置 Date 对象中的月份 (0 ~ 11)。
+
{{jsxref("Date.prototype.setUTCSeconds()")}}
+
根据世界时设置 Date 对象中的秒钟 (0 ~ 59)。
+
{{jsxref("Date.prototype.setYear()")}} {{deprecated_inline}}
+
setYear() 方法用于设置年份。请使用 {{jsxref("Global_Objects/Date/setFullYear", "setFullYear()")}} 方法代替。
+
+ +

Conversion getter

+ +
+
{{jsxref("Date.prototype.toDateString()")}}
+
以人类易读(human-readable)的形式返回该日期对象日期部分的字符串。
+
{{jsxref("Date.prototype.toISOString()")}}
+
把一个日期转换为符合 ISO 8601 扩展格式的字符串。
+
{{jsxref("Date.prototype.toJSON()")}}
+
使用 {{jsxref("Global_Objects/Date/toISOString", "toISOString()")}} 返回一个表示该日期的字符串。为了在 {{jsxref("JSON.stringify()")}} 方法中使用。
+
{{jsxref("Date.prototype.toGMTString()")}} {{deprecated_inline}}
+
返回一个基于 GMT (UT) 时区的字符串来表示该日期。请使用 {{jsxref("Global_Objects/Date/toUTCString", "toUTCString()")}} 方法代替。
+
{{jsxref("Date.prototype.toLocaleDateString()")}}
+
返回一个表示该日期对象日期部分的字符串,该字符串格式与系统设置的地区关联(locality sensitive)。
+
{{jsxref("Date.prototype.toLocaleFormat()")}} {{non-standard_inline}}
+
使用格式字符串将日期转换为字符串。
+
{{jsxref("Date.prototype.toLocaleString()")}}
+
返回一个表示该日期对象的字符串,该字符串与系统设置的地区关联(locality sensitive)。覆盖了 {{jsxref("Global_Objects/Object/toLocaleString", "Object.prototype.toLocaleString()")}} 方法。
+
{{jsxref("Date.prototype.toLocaleTimeString()")}}
+
返回一个表示该日期对象时间部分的字符串,该字符串格式与系统设置的地区关联(locality sensitive)。
+
{{jsxref("Date.prototype.toSource()")}}{{non-standard_inline}}
+
返回一个与{{jsxref("Date")}}等价的原始字符串对象,你可以使用这个值去生成一个新的对象。重写了 {{jsxref("Object.prototype.toSource()")}} 这个方法。
+
{{jsxref("Date.prototype.toString()")}}
+
返回一个表示该日期对象的字符串。覆盖了{{jsxref("Object.prototype.toString()")}} 方法。
+
{{jsxref("Date.prototype.toTimeString()")}}
+
以人类易读格式返回日期对象时间部分的字符串。
+
{{jsxref("Date.prototype.toUTCString()")}}
+
把一个日期对象转换为一个以UTC时区计时的字符串。
+
{{jsxref("Date.prototype.valueOf()")}}
+
返回一个日期对象的原始值。覆盖了 {{jsxref("Object.prototype.valueOf()")}} 方法。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.9.5', 'Date.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-the-date-prototype-object', 'Date.prototype')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-properties-of-the-date-prototype-object', 'Date.prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.prototype")}}

diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setdate/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setdate/index.html new file mode 100644 index 0000000000..e044a3b9f3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setdate/index.html @@ -0,0 +1,79 @@ +--- +title: Date.prototype.setDate() +slug: Web/JavaScript/Reference/Global_Objects/Date/setDate +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setDate +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

setDate() 方法根据本地时间来指定一个日期对象的天数。

+ +
{{EmbedInteractiveExample("pages/js/date-setdate.html")}}
+ + + +

语法

+ +
dateObj.setDate(dayValue)
+ +

参数

+ +
+
dayValue
+
一个整数,表示该月的第几天。
+
+ +

描述

+ +

如果 dayValue 超出了月份的合理范围,setDate 将会相应地更新 Date 对象。

+ +

例如,如果为 dayValue 指定0,那么日期就会被设置为上个月的最后一天。

+ +

如果dayValue被设置为负数,日期会设置为上个月最后一天往前数这个负数绝对值天数后的日期。-1会设置为上月最后一天的前一天(译者注:例如当前为4月,如果setDate(-2),则为3月29日)

+ +

例子

+ +

例子:使用setDate方法

+ +
var theBigDay = new Date(1962, 6, 7); // 1962-07-07
+theBigDay.setDate(24);  // 1962-07-24
+theBigDay.setDate(32);  // 1962-08-01
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.36', 'Date.prototype.setDate')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-date.prototype.setdate', 'Date.prototype.setDate')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setDate")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setfullyear/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setfullyear/index.html new file mode 100644 index 0000000000..7f6b70ac9a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setfullyear/index.html @@ -0,0 +1,81 @@ +--- +title: Date.prototype.setFullYear() +slug: Web/JavaScript/Reference/Global_Objects/Date/setFullYear +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setFullYear +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

setFullYear() 方法根据本地时间为一个日期对象设置年份。

+ +
{{EmbedInteractiveExample("pages/js/date-setfullyear.html")}}
+ + + +

语法

+ +
dateObj.setFullYear(yearValue[, monthValue[, dayValue]])
+ +

参数

+ +
+
yearValue
+
指定年份的整数值,例如1995。
+
monthValue
+
一个0到11之间的整数值,表示从一月到十二月。
+
dayValue
+
一个1到31之间的整数值,表示月份中的第几天。如果你指定了 dayValue 参数,就必须同时指定 monthValue
+
+ +

描述

+ +

如果没有指定 monthValuedayValue 参数,将会使用 getMonthgetDate 方法的返回值。

+ +

如果有一个参数超出了合理的范围,setFullYear 方法会更新其他参数值,日期对象的日期值也会被相应更新。 例如,为 monthValue 指定 15, 则年份会加1,月份值会为3。

+ +

例子

+ +

例子:使用setFullYear方法

+ +
var theBigDay = new Date();
+theBigDay.setFullYear(1997);
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.3StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.40', 'Date.prototype.setFullYear')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setfullyear', 'Date.prototype.setFullYear')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setFullYear")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/sethours/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/sethours/index.html new file mode 100644 index 0000000000..f23dab9d13 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/sethours/index.html @@ -0,0 +1,88 @@ +--- +title: Date.prototype.setHours() +slug: Web/JavaScript/Reference/Global_Objects/Date/setHours +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setHours +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

setHours() 方法根据本地时间为一个日期对象设置小时数,返回从1970-01-01 00:00:00 UTC 到更新后的 {{jsxref("Global_Objects/Date", "日期")}} 对象实例所表示时间的毫秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-sethours.html")}}
+ + + +

语法

+ +
dateObj.setHours(hoursValue[, minutesValue[, secondsValue[, msValue]]])
+
+ +

JavaScript 1.3版本之前

+ +
dateObj.setHours(hoursValue) 
+ +

参数

+ +
+
hoursValue
+
一个 0 到 23 的整数,表示小时。
+
minutesValue
+
一个 0 到 59 的整数,表示分钟。
+
secondsValue
+
一个 0 到 59 的整数,表示秒数。如果指定了 secondsValue 参数,则必须同时指定 minutesValue 参数。
+
msValue
+
一个 0 到 999 的数字,表示微秒数,如果指定了 msValue 参数,则必须同时指定 minutesValue 和 secondsValue 参数。
+
+ +

描述

+ +

如果不指定 minutesValuesecondsValue 和 msValue 参数,则会使用{{jsxref("Date.getMinutes", "getMinutes()")}},{{jsxref("Date.getSeconds", "getSeconds()")}} 和{{jsxref("Date.getMilliseconds", "getMilliseconds()")}} 方法的返回值。

+ +

如果有一个参数超出了合理范围,setHours 会相应地更新日期对象中的日期信息。例如,如果为 secondsValue 指定了 100,则分钟会加 1,然后秒数使用 40。

+ +

例子

+ +

例子:使用setHours方法

+ +
var theBigDay = new Date();
+theBigDay.setHours(7);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.34', 'Date.prototype.setHours')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.sethours', 'Date.prototype.setHours')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setHours")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setmilliseconds/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setmilliseconds/index.html new file mode 100644 index 0000000000..8eac30a518 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setmilliseconds/index.html @@ -0,0 +1,75 @@ +--- +title: Date.prototype.setMilliseconds() +slug: Web/JavaScript/Reference/Global_Objects/Date/setMilliseconds +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setMilliseconds +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

setMilliseconds() 方法会根据本地时间设置一个日期对象的豪秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-setmilliseconds.html")}}
+ + + +

语法

+ +
dateObj.setMilliseconds(millisecondsValue)
+ +

参数

+ +
+
millisecondsValue
+
一个 0 到 999 的数字,表示豪秒数。
+
+ +

描述

+ +

如果指定的数字超出了合理范围,则日期对象的时间信息会被相应地更新。例如,如果指定了 1005,则秒数加 1,豪秒数为 5。

+ +

例子

+ +

例子:使用setMilliseconds

+ +
var theBigDay = new Date();
+theBigDay.setMilliseconds(100);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.3StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.28', 'Date.prototype.setMilliseconds')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setmilliseconds', 'Date.prototype.setMilliseconds')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setMilliseconds")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setminutes/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setminutes/index.html new file mode 100644 index 0000000000..13421b2817 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setminutes/index.html @@ -0,0 +1,91 @@ +--- +title: Date.prototype.setMinutes() +slug: Web/JavaScript/Reference/Global_Objects/Date/setMinutes +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setMinutes +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

setMinutes() 方法根据本地时间为一个日期对象设置分钟数。

+ +
{{EmbedInteractiveExample("pages/js/date-setminutes.html")}}
+ + + +

语法

+ +
dateObj.setMinutes(minutesValue[, secondsValue[, msValue]])
+ +

 JavaScript 1.3之前版本

+ +
dateObj.setMinutes(minutesValue)
+ +

参数

+ +
+
minutesValue
+
一个 0 到 59 的整数,表示分钟数。
+
+ +
+
secondsValue
+
一个 0 到 59 的整数,表示秒数。如果指定了 secondsValue 参数,则必须同时指定 minutesValue 参数。
+
+ +
+
msValue
+
一个 0 到 999 的数字,表示微秒数,如果指定了 msValue 参数,则必须同时指定 minutesValuesecondsValue 参数。
+
+ +

描述

+ +

如果没有指定 secondsValuemsValue 参数,就会使用 {{jsxref("Date.getSeconds", "getSeconds()")}} 和 {{jsxref("Date.getMilliseconds", "getmilliseconds()")}} 方法的返回值。

+ +

如果有一个指定的参数超出了合理范围,setMinutes 会相应地更新日期对象中的时间信息。例如,为 secondsValue 指定 100,分钟数将会加 1,而秒数会为 40。

+ +

例子

+ +

例子:使用setMinutes方法

+ +
var theBigDay = new Date();
+theBigDay.setMinutes(45);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.32', 'Date.prototype.setMinutes')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setminutes', 'Date.prototype.setMinutes')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setMinutes")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setmonth/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setmonth/index.html new file mode 100644 index 0000000000..010cf5f428 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setmonth/index.html @@ -0,0 +1,86 @@ +--- +title: Date.prototype.setMonth() +slug: Web/JavaScript/Reference/Global_Objects/Date/setMonth +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setMonth +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

setMonth() 方法根据本地时间为一个设置年份的日期对象设置月份。

+ +
{{EmbedInteractiveExample("pages/js/date-setmonth.html")}}
+ +

语法

+ +
dateObj.setMonth(monthValue[, dayValue])
+ +

JavaScript 1.3版本之前

+ +
dateObj.setMonth(monthValue)
+ +

参数

+ +
+
monthValue
+
介于 0 到 11 之间的整数(表示一月到十二月)。
+
+ +
+
dayValue
+
从 1 到 31 之间的整数,表示月份中的第几天。0为上个月最后一天
+
返回值!
+
基于 1 January 1970 00:00:00 UTC 开始计算的毫秒数
+
+ +

描述

+ +

如果不指定 dayValue 参数,就会使用 {{jsxref("Date.getDate", "getDate")}} 方法的返回值。

+ +

如果有一个指定的参数超出了合理范围,setMonth 会相应地更新日期对象中的日期信息。例如,为 monthValue 指定 15,则年份会加 1,月份将会使用 3。

+ +

例子

+ +

例子:使用setMonth方法

+ +
var theBigDay = new Date();
+theBigDay.setMonth(6);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.38', 'Date.prototype.setMonth')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-date.prototype.setmonth', 'Date.prototype.setMonth')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setMonth")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setseconds/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setseconds/index.html new file mode 100644 index 0000000000..5ace67cce9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setseconds/index.html @@ -0,0 +1,83 @@ +--- +title: Date.prototype.setSeconds() +slug: Web/JavaScript/Reference/Global_Objects/Date/setSeconds +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setSeconds +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

setSeconds() 方法根据本地时间设置一个日期对象的秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-setseconds.html")}}
+ + + +

语法

+ +
dateObj.setSeconds(secondsValue[, msValue])
+ +

JavaScript 1.3之前版本

+ +
dateObj.setSeconds(secondsValue)
+ +

参数

+ +
+
secondsValue
+
一个 0 到 59 的整数。
+
msValue
+
一个 0 到 999 的数字,表示微秒数。
+
+ +

描述

+ +

如果没有指定 msValue 参数,就会使用 {{jsxref("Date.getMilliseconds", "getMilliseconds()")}} 方法的返回值。

+ +

如果一个参数超出了合理范围, setSeconds 方法会相应地更新日期对象的时间信息。例如,为 secondsValue 指定 100,则日期对象的分钟数会相应地加 1,秒数将会使用 40。

+ +

例子

+ +

例子:使用setSeconds方法

+ +
var theBigDay = new Date();
+theBigDay.setSeconds(30)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.30', 'Date.prototype.setSeconds')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setseconds', 'Date.prototype.setSeconds')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setSeconds")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/settime/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/settime/index.html new file mode 100644 index 0000000000..85fe608f8e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/settime/index.html @@ -0,0 +1,80 @@ +--- +title: Date.prototype.setTime() +slug: Web/JavaScript/Reference/Global_Objects/Date/setTime +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setTime +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

setTime() 方法以一个表示从1970-1-1 00:00:00 UTC计时的毫秒数为来为 Date 对象设置时间。

+ +
{{EmbedInteractiveExample("pages/js/date-settime.html")}}
+ + + +

语法

+ +
dateObj.setTime(timeValue)
+ +

参数

+ +
+
timeValue
+
一个整数,表示从1970-1-1 00:00:00 UTC开始计时的毫秒数。
+
+

返回值

+
+
UTC 1970年1月1日00:00:00与更新日期之间的毫秒数(实际上是自变量的值)。
+
+ +

描述

+ +

使用 setTime 方法用来把一个日期时间赋值给另一个 Date 对象。

+ +

例子

+ +

例子:使用setTime

+ +
theBigDay = new Date("July 1, 1999");
+sameAsBigDay = new Date();
+sameAsBigDay.setTime(theBigDay.getTime());
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.27', 'Date.prototype.setTime')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-date.prototype.settime', 'Date.prototype.setTime')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setTime")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setutcdate/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setutcdate/index.html new file mode 100644 index 0000000000..8f0a425e96 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setutcdate/index.html @@ -0,0 +1,77 @@ +--- +title: Date.prototype.setUTCDate() +slug: Web/JavaScript/Reference/Global_Objects/Date/setUTCDate +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setUTCDate +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

setUTCDate() 方法就是根据全球时间设置特定date对象的日期。

+ +
{{EmbedInteractiveExample("pages/js/date-setutcdate.html")}}
+ + + +

语法

+ +
dateObj.setUTCDate(dayValue)
+ +

参数

+ +
+
dayValue
+
一个1-31的整形数字,用来指定日期。
+
+ +

描述

+ +

如果你指定的参数超出了范围,setUTCDate()会尝试更新对应的{{jsxref("Global_Objects/Date", "Date")}} 中的日期信息。例如,如果你使用了40来作为参数,但是{{jsxref("Global_Objects/Date", "Date")}} 中存储的月份为6月,那么日期将被改写为10且月份被增到7月。

+ +

示例

+ +

使用Using setUTCDate()

+ +
var theBigDay = new Date();
+theBigDay.setUTCDate(20);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.37', 'Date.prototype.setUTCDate')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setutcdate', 'Date.prototype.setUTCDate')}}{{Spec2('ES6')}} 
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.builtins.Date.setUTCDate")}}

+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setutcfullyear/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setutcfullyear/index.html new file mode 100644 index 0000000000..cf971aa9c2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setutcfullyear/index.html @@ -0,0 +1,94 @@ +--- +title: Date.prototype.setUTCFullYear() +slug: Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear +tags: + - Date + - JavaScript + - Method + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear +--- +
{{JSRef}}
+ +

setUTCFullYear() 方法根据世界标准时间为一个具体日期设置年份。

+ +
{{EmbedInteractiveExample("pages/js/date-setutcfullyear.html")}}
+ + + +

语法

+ +
dateObj.setUTCFullYear(yearValue[, monthValue[, dayValue]])
+ +

参数

+ +
+
yearValue
+
指定年份整数值,例如,1995
+
monthValue
+
可选。指定一个0-11之间的整数值,代表从一月到十二月。
+
dayValue
+
可选。指定一个1-31之间的整数值,代表月份中的第几天。如果你指定了dayValue参数,那么你必须指定monthValue参数。
+
+ +

描述

+ +

如果你没有指定具体的monthValue和dayValue,将会使用 getUTCMonth 和getUTCDate 方法的返回值。

+ +

如果你指定的参数超出了期待范围,setUTCFullYear()方法将会根据Date对象,更新其他参数和日期信息。例如,如果你将monthValue设定为15,年份会增加1,月份值则为为3。

+ +

例子

+ +

使用 setUTCFullYear()

+ +
var theBigDay = new Date();
+theBigDay.setUTCFullYear(1997);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}初始定义。 在 JavaScript 1.3实施。
{{SpecName('ES5.1', '#sec-15.9.5.41', 'Date.prototype.setUTCFullYear')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setutcfullyear', 'Date.prototype.setUTCFullYear')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.setutcfullyear', 'Date.prototype.setUTCFullYear')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.setUTCFullYear")}}

+
+ +

相关连接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setutchours/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setutchours/index.html new file mode 100644 index 0000000000..16d4989a4b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setutchours/index.html @@ -0,0 +1,94 @@ +--- +title: Date.prototype.setUTCHours() +slug: Web/JavaScript/Reference/Global_Objects/Date/setUTCHours +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setUTCHours +--- +
{{JSRef}}
+ +

The setUTCHours() method sets the hour for a specified date according to universal time, and returns the number of milliseconds since 1 January 1970 00:00:00 UTC until the time represented by the updated {{jsxref("Date")}} instance.

+ +
{{EmbedInteractiveExample("pages/js/date-setutchours.html")}}
+ + + +

Syntax

+ +
dateObj.setUTCHours(hoursValue[, minutesValue[, secondsValue[, msValue]]])
+ +

 参数

+ +
+
hoursValue
+
表示小时的整数,取值0到23之间。
+
minutesValue
+
可选参数。表示分钟的整数,取值0到59之间。
+
secondsValue
+
可选参数。表示秒数的整数,取值0到59之间。如果指定了该参数,就要同时指定minutesValue这个参数。
+
msValue
+
可选参数。表示毫秒的整数,取值0到999之间。如果指定了该参数,就要指定minutesValue和secondsValue这两个参数。
+
+ +

返回值

+ +

返回从1970-01-01 00:00:00 UTC 到更新后的日期所表示时间的毫秒数。

+ +

描述

+ +

If you do not specify the minutesValue, secondsValue, and msValue parameters, the values returned from the {{jsxref("Date.prototype.getUTCMinutes()", "getUTCMinutes()")}}, {{jsxref("Date.prototype.getUTCSeconds()", "getUTCSeconds()")}}, and {{jsxref("Date.prototype.getUTCMilliseconds()", "getUTCMilliseconds()")}} methods are used.

+ +

If a parameter you specify is outside of the expected range, setUTCHours() attempts to update the date information in the {{jsxref("Date")}} object accordingly. For example, if you use 100 for secondsValue, the minutes will be incremented by 1 (minutesValue + 1), and 40 will be used for seconds.

+ +

例子

+ +

使用 setUTCHours()

+ +
var theBigDay = new Date();
+theBigDay.setUTCHours(8);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.9.5.35', 'Date.prototype.setUTCHours')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setutchours', 'Date.prototype.setUTCHours')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.setutchours', 'Date.prototype.setUTCHours')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.setUTCHours")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setutcmilliseconds/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setutcmilliseconds/index.html new file mode 100644 index 0000000000..b3059be4cb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setutcmilliseconds/index.html @@ -0,0 +1,84 @@ +--- +title: Date.prototype.setUTCMilliseconds() +slug: Web/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds +--- +
{{JSRef}}
+ +

setUTCMilliseconds() 方法会根据世界时来设置指定时间的毫秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-setutcmilliseconds.html")}}
+ + + +

语法

+ +
dateObj.setUTCMilliseconds(millisecondsValue)
+ +

参数

+ +
+
millisecondsValue
+
0 - 999 之间的数值,代表毫秒数。
+
+ +

返回值

+ +

返回更新后的时间距 1970 年 1 月 1 日 00:00:00 (UTC) 的毫秒数。

+ +

描述

+ +

如果传递的参数超出了指定的范围,setUTCMilliseconds() 方法会相应地尝试更新储存在 {{jsxref("Date")}}  的时间信息。例如,假设你传递参数的值是 1100,存储在 {{jsxref("Date")}} 的秒数会加 1,然后使用 100 来作为毫秒数。

+ +

示例

+ +

使用 setUTCMilliseconds() 方法

+ +
var theBigDay = new Date();
+theBigDay.setUTCMilliseconds(500);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}初始定义。于 JavaScript 1.3 实现。
{{SpecName('ES5.1', '#sec-15.9.5.29', 'Date.prototype.setUTCMilliseconds')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setutcmilliseconds', 'Date.prototype.setUTCMilliseconds')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.setutcmilliseconds', 'Date.prototype.setUTCMilliseconds')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setUTCMilliseconds")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setutcminutes/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setutcminutes/index.html new file mode 100644 index 0000000000..7ea6d1ed0b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setutcminutes/index.html @@ -0,0 +1,92 @@ +--- +title: Date.prototype.setUTCMinutes() +slug: Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes +--- +
{{JSRef}}
+ +
 
+ +

setUTCMinutes()方法会根据世界协调时(UTC)来设置指定日期的分钟数。

+ +
{{EmbedInteractiveExample("pages/js/date-setutcminutes.html")}}
+ + + +

语法

+ +
dateObj.setUTCMinutes(minutesValue[, secondsValue[, msValue]])
+ +

参数

+ +
+
minutesValue
+
必填,表示要设置的分钟数,是一个介于0和59之间的整数。
+
secondsValue
+
可选参数,表示要设置的秒数,同样也是一个介于0和59之间的整数,如果你传入了这个参数,那么你就必须要传入上一个参数(minutesValue)。
+
msValue
+
可选参数,表示要设置的毫秒数,这是一个介于0和999之间的数字,如果你传入了这个参数,那么你就必须要传入前面两个参数(minutesValuesecondsValue)。
+
+ +

返回值

+ +

返回从UTC时间1970年1月1日0时0分0秒至设置后的时间的毫秒数。

+ +

说明

+ +

如果你没有传入后两个参数(minutesValuemsValue),这两个参数会分别使用{{jsxref("Date.prototype.getUTCSeconds()", "getUTCSeconds()")}}和{{jsxref("Date.prototype.getUTCMilliseconds()", "getUTCMilliseconds()")}}这两个方法返回的值。

+ +

如果你传入的参数值在上文所述范围之外的话,setUTCMinutes()方法会尝试修改日期对象中的其他信息,比如说你为secondsValue这个参数传入了100(译者注:规定范围是[0, 59]),那么第一个参数(minutesValue)就会被加1,而秒数则变成了40。

+ +

例子

+ +

使用 setUTCMinutes()

+ +
var theBigDay = new Date();
+theBigDay.setUTCMinutes(43);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES1')}}{{Spec2('ES1')}}首次被定义,在JavaScript 1.3版本被实现。
{{SpecName('ES5.1', '#sec-15.9.5.33', 'Date.prototype.setUTCMinutes')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setutcminutes', 'Date.prototype.setUTCMinutes')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.setutcminutes', 'Date.prototype.setUTCMinutes')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setUTCMinutes")}}

+ +

相关知识

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setutcmonth/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setutcmonth/index.html new file mode 100644 index 0000000000..0e3ffb7782 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setutcmonth/index.html @@ -0,0 +1,90 @@ +--- +title: Date.prototype.setUTCMonth() +slug: Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth +--- +
{{JSRef}}
+ +

setUTCMonth()方法根据通用的时间来设置一个准确的月份

+ +
{{EmbedInteractiveExample("pages/js/date-setutcmonth.html")}}
+ + + +

语法

+ +
dateObj.setUTCMonth(monthValue[, dayValue])
+ +

参数

+ +
+
monthValue
+
一个0-11的整数,代表1月到12月。
+
dayValue
+
可选参数:一个1-31的整数,代表一个月的天数。
+
+ +

返回值

+ +

这个数值是从1970年1月1号 00:00:00到当前时间的毫秒数(国际通用时间)

+ +

描述

+ +

如果你没有明确书写dayValue 这个参数,那么就会从{{jsxref("Date.prototype.getUTCDate()", "getUTCDate()")}} 方法返回对应的数值.

+ +

如果你写了一个超过在规定的范围内的参数. setUTCMonth()就会试图相应的更新时间信息在Data对象中。例如,如果你用15作为monthValue的值,那么年份就会加1,并且月份会变成3.(15=12+3)

+ +

示例

+ +

使用 setUTCMonth()

+ +
var theBigDay = new Date();
+theBigDay.setUTCMonth(11);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ES1')}}{{Spec2('ES1')}}最初定义并使用在javascript 1.3版本中
{{SpecName('ES5.1', '#sec-15.9.5.39', 'Date.prototype.setUTCMonth')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setutcmonth', 'Date.prototype.setUTCMonth')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.setutcmonth', 'Date.prototype.setUTCMonth')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.setUTCMonth")}}

+
+ +

更多

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setutcseconds/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setutcseconds/index.html new file mode 100644 index 0000000000..fce240e115 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setutcseconds/index.html @@ -0,0 +1,92 @@ +--- +title: Date.prototype.setUTCSeconds() +slug: Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds +tags: + - 日期 +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds +--- +
{{JSRef}}
+ +

此 setUTCSeconds() 方法为一个依据国际通用时间的特定日期设置秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-setutcseconds.html")}}
+ + + +

语法

+ +
dateObj.setUTCSeconds(secondsValue[, msValue])
+ +

参数

+ +
+
secondsValue
+
一个在0到59之间的整数,表示秒数。
+
msValue
+
可选参数。一个0到999之间的数字,代表毫秒数。
+
+ +

返回值

+ +

一个毫秒数,表示从国际通用时间1970年00:00:00到设置的时间值之间的时间跨度。

+ +

描述

+ +

如果你没有设置msValue参数的值, 那么返回的值来自{{jsxref("Date.prototype.getUTCMilliseconds()", "getUTCMilliseconds()")}} 方法。

+ +

如果你指定的值超出了范围, setUTCSeconds() 因此会更新{{jsxref("Date")}} 对象中date的相关信息 . 举个例子, 如果你设置secondsValue为100, {{jsxref("Date")}} 对象中的分钟数会增加1, 并且秒数会变成40.

+ +

示例

+ +

使用 setUTCSeconds()

+ +
var theBigDay = new Date();
+theBigDay.setUTCSeconds(20);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
说明状态备注
{{SpecName('ES1')}}{{Spec2('ES1')}}初始化设定. 从 JavaScript 1.3继承.
{{SpecName('ES5.1', '#sec-15.9.5.31', 'Date.prototype.setUTCSeconds')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.setutcseconds', 'Date.prototype.setUTCSeconds')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.setutcseconds', 'Date.prototype.setUTCSeconds')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.setUTCSeconds")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/setyear/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/setyear/index.html new file mode 100644 index 0000000000..7999ad0022 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/setyear/index.html @@ -0,0 +1,72 @@ +--- +title: Date.prototype.setYear() +slug: Web/JavaScript/Reference/Global_Objects/Date/setYear +tags: + - JavaScript + - 已废弃 + - 日期 +translation_of: Web/JavaScript/Reference/Global_Objects/Date/setYear +--- +
{{JSRef}} {{deprecated_header}}
+ +

setYear() 方法根据一个本地时间为一个确定的日期对象设置年份。由于setYear() 并不设置完整年份("正是千年虫问题"),本方法已经完全被{{jsxref("Date.prototype.setFullYear()","setFullYear()")}} 方法所取代。

+ +

语法

+ +
dateObj.setYear(yearValue)
+ +

参数

+ +
+
yearValue
+
一个整数。
+
+ +

返回值

+ +

介于1970年1月1日 00:00:00 UTC时间与更新后日期的毫秒数。

+ +

描述

+ +

如果yearValue 是介于0到99(包含99)之间的整数,则目标对象 dateObj 的年份被设置为 1900 + yearValue。否则,目标对象 dateObj 的年份被设置为 yearValue.

+ +

例子

+ +

使用 setYear()

+ +

例子前两行(除去声明)将年份设置为1996。 第三行将年份设置为2000.

+ +
var theBigDay = new Date();
+
+theBigDay.setYear(96);
+theBigDay.setYear(1996);
+theBigDay.setYear(2000);
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-date.prototype.setyear', 'Date.prototype.setYear')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.setYear")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/todatestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/todatestring/index.html new file mode 100644 index 0000000000..e2216ea015 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/todatestring/index.html @@ -0,0 +1,72 @@ +--- +title: Date.prototype.toDateString() +slug: Web/JavaScript/Reference/Global_Objects/Date/toDateString +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toDateString +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

toDateString() 方法以美式英语和人类易读的形式返回一个日期对象日期部分的字符串。

+ +
{{EmbedInteractiveExample("pages/js/date-todatestring.html")}}
+ + + +

语法

+ +
dateObj.toDateString()
+ +

描述

+ +

{{jsxref("Global_Objects/Date", "Date")}} 对象实例引用一个具体的时间点。调用 {{jsxref("Date.toString", "toString")}} 方法会以美式英语和人类易读的形式返回日期对象的格式化字符串。在 SpiderMonkey 里,该字符串由日期部分(年月日)和其后的时间部分(时分秒及时区)组成。有时需要获取日期部分的字符串,这可以由 toDateString 方法完成。

+ +

The toDateString method is especially useful because compliant engines implementing ECMA-262 may differ in the string obtained from toString for Date objects, as the format is implementation-dependent and simple string slicing approaches may not produce consistent results across multiple engines.

+ +

例子

+ +

例子:toDateString 方法的简单使用

+ +
var d = new Date(1993, 6, 28, 14, 39, 7);
+
+println(d.toString());     // prints Wed Jul 28 1993 14:39:07 GMT-0600 (PDT)
+println(d.toDateString()); // prints Wed Jul 28 1993
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 3rd Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.3', 'Date.prototype.toDateString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.todatestring', 'Date.prototype.toDateString')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.toDateString")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/togmtstring/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/togmtstring/index.html new file mode 100644 index 0000000000..4dd44803b4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/togmtstring/index.html @@ -0,0 +1,67 @@ +--- +title: Date.prototype.toGMTString() +slug: Web/JavaScript/Reference/Global_Objects/Date/toGMTString +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toGMTString +--- +
{{JSRef("Global_Objects", "Date")}} {{ Deprecated_header() }}
+ +

The toGMTString() method converts a date to a string, using Internet GMT conventions. The exact format of the value returned by toGMTString varies according to the platform and browser, in general it should represent a human readable date string.

+ +

Note: toGMTString is deprecated and should no longer be used, it's only there for backwards compatibility, use {{jsxref("Date.toUTCString", "toUTCString()")}} instead.

+ +

Syntax

+ +
dateObj.toGMTString()
+ +

Examples

+ +

Example: Using toGMTString

+ +

In this example, the toGMTString method converts the date to GMT (UTC) using the operating system's time-zone offset and returns a string value that is similar to the following form. The exact format depends on the platform.

+ +
var today = new Date();
+var str = today.toGMTString();  // deprecated! use toUTCString()
+
+console.log(str);               // Mon, 18 Dec 1995 17:28:35 GMT
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition, but already declared as deprecated.
{{SpecName('ES5.1', '#sec-B.2.6', 'Date.prototype.toGMTString')}}{{Spec2('ES5.1')}}Defined in the (informative) compatibility annex.
{{SpecName('ES6', '#sec-date.prototype.togmtstring', 'Date.prototype.toGMTString')}}{{Spec2('ES6')}}Defined in the (normative) annex for additional features for web browsers.
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Date.toGMTString")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/toisostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/toisostring/index.html new file mode 100644 index 0000000000..b93bd8c745 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/toisostring/index.html @@ -0,0 +1,89 @@ +--- +title: Date.prototype.toISOString() +slug: Web/JavaScript/Reference/Global_Objects/Date/toISOString +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toISOString +--- +
{{JSRef}}
+ +

toISOString() 方法返回一个 ISO(ISO 8601 Extended Format)格式的字符串: YYYY-MM-DDTHH:mm:ss.sssZ。时区总是UTC(协调世界时),加一个后缀“Z”标识。

+ +
{{EmbedInteractiveExample("pages/js/date-toisostring.html")}}
+ + + +

语法

+ +
dateObj.toISOString()
+ +

例子

+ +
var today = new Date("05 October 2011 14:48 UTC");
+alert(today.toISOString()); // 返回2011-10-05T14:48:00.000Z
+
+ +

上例使用了非标准字符串的解析,该字符串在某些旧的浏览器(如IE)中可能无法被正确解析。

+ +

Polyfill

+ +

该方法在ECMA-262第5版中被标准化。对于那些不支持此方法的JS引擎可以通过加上下面的代码实现:

+ +
if ( !Date.prototype.toISOString ) {
+  ( function() {
+
+    function pad(number) {
+      if ( number < 10 ) {
+        return '0' + number;
+      }
+      return number;
+    }
+
+    Date.prototype.toISOString = function() {
+      return this.getUTCFullYear() +
+        '-' + pad( this.getUTCMonth() + 1 ) +
+        '-' + pad( this.getUTCDate() ) +
+        'T' + pad( this.getUTCHours() ) +
+        ':' + pad( this.getUTCMinutes() ) +
+        ':' + pad( this.getUTCSeconds() ) +
+        '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) +
+        'Z';
+    };
+
+  }() );
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES5.1', '#sec-15.9.5.43', 'Date.prototype.toISOString')}}
+ Implemented in JavaScript 1.8
{{Spec2('ES5.1')}}Initial definition.
{{SpecName('ES6', '#sec-date.prototype.toisostring', 'Date.prototype.toISOString')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.toISOString")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/tojson/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/tojson/index.html new file mode 100644 index 0000000000..689d7b3642 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/tojson/index.html @@ -0,0 +1,73 @@ +--- +title: Date.prototype.toJSON() +slug: Web/JavaScript/Reference/Global_Objects/Date/toJSON +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toJSON +--- +
{{JSRef}}
+ +

toJSON() 方法返回 {{jsxref("Date")}} 对象的字符串形式。

+ +
{{EmbedInteractiveExample("pages/js/date-tojson.html")}}
+ + + +

语法

+ +
dateObj.toJSON()
+
+ +

描述

+ +

{{jsxref("Date")}} 实例引用一个具体的时间点。 调用 toJSON() 返回一个 JSON 格式字符串(使用 {{jsxref("Date.prototype.toISOString()", "toISOString()")}}),表示该日期对象的值。默认情况下,这个方法常用于 {{Glossary("JSON")}}序列化{{jsxref("Date")}}对象。

+ +

样例

+ +

toJSON() 样例

+ +
var date = new Date();
+console.log(date); //Thu Nov 09 2017 18:54:04 GMT+0800 (中国标准时间)
+
+var jsonDate = (date).toJSON();
+console.log(jsonDate); //"2017-11-09T10:51:11.395Z"
+
+var backToDate = new Date(jsonDate);
+console.log(backToDate); //Thu Nov 09 2017 18:54:04 GMT+0800 (中国标准时间)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES5.1', '#sec-15.9.5.44', 'Date.prototype.toJSON')}}{{Spec2('ES5.1')}}首次定义,于 JavaScript 1.8.5 版本实现。
{{SpecName('ES6', '#sec-date.prototype.tojson', 'Date.prototype.toJSON')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.toJSON")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/tolocaledatestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/tolocaledatestring/index.html new file mode 100644 index 0000000000..b5dfe22d12 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/tolocaledatestring/index.html @@ -0,0 +1,155 @@ +--- +title: Date.prototype.toLocaleDateString() +slug: Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

toLocaleDateString() 方法返回该日期对象日期部分的字符串,该字符串格式因不同语言而不同。新增的参数 locales 和 options 使程序能够指定使用哪种语言格式化规则,允许定制该方法的表现(behavior)。在旧版本浏览器中, localesoptions 参数被忽略,使用的语言环境和返回的字符串格式是各自独立实现的。

+ +
{{EmbedInteractiveExample("pages/js/date-tolocaledatestring.html")}}
+ + + +

语法

+ +
dateObj.toLocaleDateString([locales [, options]])
+ +

参数

+ +

 查看浏览器兼容性小节,看下哪些浏览器支持 locales 和 options 参数,还可以参看例子: 检测 localesoptions 参数支持情况

+ +

{{page('zh-CN/docs/JavaScript/Reference/Global_Objects/DateTimeFormat','Parameters')}}

+ +

The default value for each date-time component property is undefined, but if the weekday, year, month, day properties are all undefined, then year, month, and day are assumed to be "numeric".

+ +

例子

+ +

例子:使用toLocaleDateString

+ +

没有指定语言环境(locale)时,返回一个使用默认语言环境和格式设置(options)的格式化字符串。

+ +
var date = new Date(Date.UTC(2012, 11, 12, 3, 0, 0));
+
+// toLocaleDateString without arguments depends on the implementation,
+// the default locale, and the default time zone
+date.toLocaleDateString();
+// → "12/11/2012" if run in en-US locale with time zone America/Los_Angeles
+ +

例子:检测 localesoptions 参数支持情况

+ +

locales 和 options 参数不是所有的浏览器都支持。为了检测一种实现环境(implementation)是否支持它们,可以使用不合法的语言标签,如果实现环境支持该参数,则会抛出一个 RangeError 异常,反之会忽略参数。

+ +
function toLocaleDateStringSupportsLocales() {
+    try {
+        new Date().toLocaleDateString("i");
+    } catch (e) {
+        return e​.name === "RangeError";
+    }
+    return false;
+}
+
+ +

例子:使用locales

+ +

下例展示了本地化日期格式的一些变化。为了在应用的用户界面得到某种语言的日期格式,必须确保使用 locales 参数指定了该语言(可能还需要设置某些回退语言)。

+ +
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
+
+// formats below assume the local time zone of the locale;
+// America/Los_Angeles for the US
+
+// US English uses month-day-year order
+alert(date.toLocaleDateString("en-US"));
+// → "12/19/2012"
+
+// British English uses day-month-year order
+alert(date.toLocaleDateString("en-GB"));
+// → "20/12/2012"
+
+// Korean uses year-month-day order
+alert(date.toLocaleDateString("ko-KR"));
+// → "2012. 12. 20."
+
+// Arabic in most Arabic speaking countries uses real Arabic digits
+alert(date.toLocaleDateString("ar-EG"));
+// → "٢٠‏/١٢‏/٢٠١٢"
+
+// for Japanese, applications may want to use the Japanese calendar,
+// where 2012 was the year 24 of the Heisei era
+alert(date.toLocaleDateString("ja-JP-u-ca-japanese"));
+// → "24/12/20"
+
+// when requesting a language that may not be supported, such as
+// Balinese, include a fallback language, in this case Indonesian
+alert(date.toLocaleDateString(["ban", "id"]));
+// → "20/12/2012"
+
+ +

例子:使用options

+ +

可以使用 options 参数来自定义 toLocaleDateString 方法返回的字符串。

+ +
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
+
+// request a weekday along with a long date
+var options = {weekday: "long", year: "numeric", month: "long", day: "numeric"};
+alert(date.toLocaleDateString("de-DE", options));
+// → "Donnerstag, 20. Dezember 2012"
+
+// an application may want to use UTC and make that visible
+options.timeZone = "UTC";
+options.timeZoneName = "short";
+alert(date.toLocaleDateString("en-US", options));
+// → "Thursday, December 20, 2012, GMT"
+
+ +

性能

+ +

当格式化大量日期时,最好创建一个 Intl.DateTimeFormat 对象,然后使用该对象 format 属性提供的方法。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 3rd Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', 'sec-15.9.5.6', 'Date.prototype.toLocaleDateString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.tolocaledatestring', 'Date.prototype.toLocaleDateString')}}{{Spec2('ES6')}} 
ECMAScript Internationalization API Specification, 1st EditionStandardDefines locales and options arguments.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.toLocaleDateString")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/tolocaleformat/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/tolocaleformat/index.html new file mode 100644 index 0000000000..40c72fc476 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/tolocaleformat/index.html @@ -0,0 +1,73 @@ +--- +title: Date.prototype.toLocaleFormat() +slug: Web/JavaScript/Reference/Global_Objects/Date/toLocaleFormat +tags: + - Date + - 非标准 +translation_of: Archive/Web/JavaScript/Date.toLocaleFormat +--- +
{{JSRef}} {{non-standard_header}}
+ +

非标准方法 toLocaleFormat() 按特定的格式将一个日期转换成一个字符串。 {{jsxref("Global_Objects/DateTimeFormat", "Intl.DateTimeFormat")}} 是符合标准的格式化日期的替代方法。另见更新的(newer)版本的 {{jsxref("Date.prototype.toLocaleDateString()")}}方法.

+ +

语法

+ +
dateObj.toLocaleFormat(formatString)
+ +

参数

+ +
+
formatString
+
与C语言中的 strftime() 方法的参数形式要求相同的格式字符串。
+
+ +

描述

+ +

toLocaleFormat() 方法通过格式化生成的日期或时间提供了更好的软件层面的控制(provides greater software control over the formatting of the generated date and/or time)。用操作系统的地点来月份和星期几的名称本地化。然而,However, ordering of the day and month and other localization tasks are not handled automatically since you have control over the order in which they occur. You should take care that the format string is localized properly according to the user's system settings. Be aware that the locale used is not necessarily the same as the locale of the browser.

+ +

Extension and XULRunner developers should know that just loading the format string from a .dtd or .properties file using a chrome://somedomain/locale/somefile.ext URI should be avoided, as the .dtd/.properties file and the toLocaleFormat() method does not not necessarily use the same locale, which could result in odd looking or even ambiguous or unreadable dates.

+ +

Also note that the behavior of the used locale depends on the platform, and the user might customize the locale used, so using the system locale the choose the format string might in some cases not even be adequate. You might consider using some of the more general toLocale* methods of the {{jsxref("Global_Objects/Date", "Date")}} object or doing your own custom localization of the date to be displayed using some of the get* methods of the {{jsxref("Global_Objects/Date", "Date")}} object instead of using this method.

+ +

示例

+ +

Using toLocaleFormat()

+ +
var today = new Date();
+var date = today.toLocaleFormat('%A, %B %e, %Y'); // Bad example
+
+ +

In this example, toLocaleFormat() returns a string such as "Wednesday, October 3, 2007". Note that the format string in this example is not properly localized, which will result in the problems described above.

+ +

腻子(Polyfill)

+ +

When using the DateJS library you can polyfill {{jsxref("Date.prototype.toLocaleDateString()")}} like this:

+ +
if (!Date.prototype.toLocaleFormat) {
+    (function() {
+        Date.prototype.toLocaleFormat = function(formatString) {
+            return this.format(formatString);
+        };
+    }());
+}
+ +

标准

+ +

不属于任何标准。在JavaScript 1.6中被实现。

+ +

兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.toLocaleFormat")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/tolocalestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/tolocalestring/index.html new file mode 100644 index 0000000000..75e2834be5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/tolocalestring/index.html @@ -0,0 +1,161 @@ +--- +title: Date.prototype.toLocaleString() +slug: Web/JavaScript/Reference/Global_Objects/Date/toLocaleString +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toLocaleString +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

toLocaleString() 方法返回该日期对象的字符串,该字符串格式因不同语言而不同。新增的参数 locales 和 options 使程序能够指定使用哪种语言格式化规则,允许定制该方法的表现(behavior)。在旧版本浏览器中, locales 和 options 参数被忽略,使用的语言环境和返回的字符串格式是各自独立实现的。

+ +
{{EmbedInteractiveExample("pages/js/date-tolocalestring.html")}}
+ + + +

语法

+ +
dateObj.toLocaleString([locales [, options]])
+ +

参数

+ +

查看浏览器兼容性小节,看下哪些浏览器支持 locales 和 options 参数,还可以参看例子:检测 localesoptions 参数支持情况

+ +

{{page('zh-CN/docs/JavaScript/Reference/Global_Objects/DateTimeFormat','Parameters')}}

+ +

每个日期时间组件的默认值都是undefined, 但是如果 weekday, year, month, day, hour, minute, second 属性都是 undefined, 那么 year, month, day, hour, minute 和 second 的值都被认为是 "numeric".

+ +

返回值

+ +

根据当地语言规定返回代表着时间的字符串。

+ +

例子

+ +

例子:使用 toLocaleString

+ +

没有指定语言环境(locale)时,返回一个使用默认语言环境和格式设置(options)的格式化字符串。

+ +
var date = new Date(Date.UTC(2012, 11, 12, 3, 0, 0));
+
+// toLocaleString 不包含参数的返回值取决于实现,
+// 默认的区域(locale),和默认的时区(time zone)
+date.toLocaleString();
+// → 如果是在en-US区域和America/Los_Angeles时区运行返回值为"12/11/2012, 7:00:00 PM"
+ +

例子:检测 locales 和 options 参数支持情况

+ +

locales 和 options 参数不是所有的浏览器都支持。为了检测一种实现环境(implementation)是否支持它们,可以使用不合法的语言标签,如果实现环境支持该参数,则会抛出一个 RangeError 异常,反之会忽略参数。

+ +
function toLocaleStringSupportsLocales() {
+    try {
+        new Date().toLocaleString("i");
+    } catch (e) {
+        return e​.name === "RangeError";
+    }
+    return false;
+}
+
+ +

例子:使用 locales 参数

+ +

下例展示了本地化日期格式的一些变化。为了在应用的用户界面得到某种语言的日期和时间格式,必须确保使用 locales 参数指定了该语言(可能还需要设置某些回退语言)。

+ +
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
+
+//假定本地时区是 America/Los_Angeles(美国时区)
+//en-US(美利坚英语)使用 month-day-year 的顺序展示年月日
+alert(date.toLocaleString("en-US"));
+// → "12/19/2012, 7:00:00 PM"
+
+// en-GB(不列颠英语)使用 day-month-year 顺序展示年月日
+alert(date.toLocaleString("en-GB"));
+// → "20/12/2012 03:00:00"
+
+// 韩语使用 year-month-day 顺序展示年月日
+alert(date.toLocaleString("ko-KR"));
+// → "2012. 12. 20. 오후 12:00:00"
+
+// 大多数阿拉伯语国家的阿拉伯语使用阿拉伯数字
+alert(date.toLocaleString("ar-EG"));
+// → "٢٠‏/١٢‏/٢٠١٢ ٥:٠٠:٠٠ ص"
+
+//在日本,应用可能想要使用日本日历,
+//2012 是平成24年(平成是是日本天皇明仁的年号,由1989年1月8日起开始计算直至现在)
+alert(date.toLocaleString("ja-JP-u-ca-japanese"));
+// → "24/12/20 12:00:00"
+
+//当请求一个语言可能不支持,如巴厘(ban),若有备用的语言印尼语(id),
+//那么将使用印尼语(id)
+alert(date.toLocaleString(["ban", "id"]));
+// → "20/12/2012 11.00.00"
+
+ +

例子:使用 options 参数

+ +

可以使用 options 参数来自定义 toLocaleString 方法返回的字符串。

+ +
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
+
+//请求参数(options)中包含参数星期(weekday),并且该参数的值为长类型(long)
+var options = {weekday: "long", year: "numeric", month: "long", day: "numeric"};
+alert(date.toLocaleString("de-DE", options));
+// → "Donnerstag, 20. Dezember 2012"
+
+//一个应用使用 世界标准时间(UTC),并且UTC使用短名字(short)展示
+options.timeZone = "UTC";
+options.timeZoneName = "short";//若不写这一行那么仍然显示的是世界标准时间;但是GMT三个字母不会显示
+alert(date.toLocaleString("en-US", options));
+// → "Thursday, December 20, 2012, GMT"
+
+// 使用24小时制
+alert(date.toLocaleString("en-US", {hour12: false}));
+// → "12/19/2012, 19:00:00"
+
+ +

性能

+ +

当格式化大量日期时,最好创建一个 Intl.DateTimeFormat 对象,然后使用该对象 format 属性提供的方法。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', 'sec-15.9.5.5', 'Date.prototype.toLocaleString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.tolocalestring', 'Date.prototype.toLocaleString')}}{{Spec2('ES6')}} 
ECMAScript Internationalization API Specification, 1st EditionStandardDefines locales and options arguments.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.toLocaleString")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/tolocaletimestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/tolocaletimestring/index.html new file mode 100644 index 0000000000..2a52a021e7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/tolocaletimestring/index.html @@ -0,0 +1,151 @@ +--- +title: Date.prototype.toLocaleTimeString() +slug: Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

The toLocaleTimeString() 方法返回该日期对象时间部分的字符串,该字符串格式因不同语言而不同。新增的参数 locales 和 options 使程序能够指定使用哪种语言格式化规则,允许定制该方法的表现(behavior)。在旧版本浏览器中, locales 和 options 参数被忽略,使用的语言环境和返回的字符串格式是各自独立实现的。

+ +
{{EmbedInteractiveExample("pages/js/date-tolocaletimestring.html")}}
+ + + +

语法

+ +
dateObj.toLocaleTimeString([locales [, options]])
+ +

参数

+ +

查看浏览器兼容性小节,看下哪些浏览器支持 locales 和 options 参数,还可以参看例子:检测 localesoptions 参数支持情况

+ +

{{page('zh-US/docs/JavaScript/Reference/Global_Objects/DateTimeFormat','Parameters')}}

+ +

The default value for each date-time component property is undefined, but if the hour, minute, second properties are all undefined, then hour, minute, and second are assumed to be "numeric".

+ +

例子

+ +

例子:使用 toLocaleTimeString

+ +

没有指定语言环境(locale)时,返回一个使用默认语言环境和格式设置(options)的格式化字符串。

+ +
var date = new Date(Date.UTC(2012, 11, 12, 3, 0, 0));
+
+// toLocaleTimeString without arguments depends on the implementation,
+// the default locale, and the default time zone
+alert(date.toLocaleTimeString());
+// → "7:00:00 PM" if run in en-US locale with time zone America/Los_Angeles
+ +

例子:检测 localesoptions 支持情况

+ +

locales 和 options 参数不是所有的浏览器都支持。为了检测一种实现环境(implementation)是否支持它们,可以使用不合法的语言标签,如果实现环境支持该参数,则会抛出一个 RangeError 异常,反之会忽略参数。

+ +
function toLocaleTimeStringSupportsLocales() {
+    try {
+        new Date().toLocaleTimeString("i");
+    } catch (e) {
+        return e​.name === "RangeError";
+    }
+    return false;
+}
+
+ +

例子:使用 locales 参数

+ +

下例展示了本地化时间格式的一些变化。为了在应用的用户界面得到某种语言的时间格式,必须确保使用 locales 参数指定了该语言(可能还需要设置某些回退语言)。

+ +
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
+
+// formats below assume the local time zone of the locale;
+// America/Los_Angeles for the US
+
+// US English uses 12-hour time with AM/PM
+alert(date.toLocaleTimeString("en-US"));
+// → "7:00:00 PM"
+
+// British English uses 24-hour time without AM/PM
+alert(date.toLocaleTimeString("en-GB"));
+// → "03:00:00"
+
+// Korean uses 12-hour time with AM/PM
+alert(date.toLocaleTimeString("ko-KR"));
+// → "오후 12:00:00"
+
+// Arabic in most Arabic speaking countries uses real Arabic digits
+alert(date.toLocaleTimeString("ar-EG"));
+// → "٧:٠٠:٠٠ م"
+
+// when requesting a language that may not be supported, such as
+// Balinese, include a fallback language, in this case Indonesian
+alert(date.toLocaleTimeString(["ban", "id"]));
+// → "11.00.00"
+
+ +

例子:使用 options 参数

+ +

可以使用 options 参数来自定义 toLocaleTimeString 方法返回的字符串。

+ +
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
+
+// an application may want to use UTC and make that visible
+var options = {timeZone: "UTC", timeZoneName: "short"};
+alert(date.toLocaleTimeString("en-US", options));
+// → "3:00:00 AM GMT"
+
+// sometimes even the US needs 24-hour time
+alert(date.toLocaleTimeString("en-US", {hour12: false}));
+// → "19:00:00"
+
+ +

性能

+ +

当格式化大量日期时,最好创建一个 Intl.DateTimeFormat 对象,然后使用该对象 format 属性提供的方法。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 3rd Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.7', 'Date.prototype.toLocaleTimeString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.tolocalestring', 'Date.prototype.toLocaleTimeString')}}{{Spec2('ES6')}} 
ECMAScript Internationalization API Specification, 1st EditionStandardDefines locales and options arguments.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.toLocaleTimeString")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/tosource/index.html new file mode 100644 index 0000000000..dbcae1c739 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/tosource/index.html @@ -0,0 +1,50 @@ +--- +title: Date.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/Date/toSource +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toSource +--- +
{{JSRef}} {{non-standard_header}}
+ +

toSource() 返回表示源代码的字符串。

+ +

语法

+ +
dateObj.toSource()
+Date.toSource()
+ +

返回值

+ +

 表示{{jsxref("Global_Objects/Date", "Date")}} 源代码的字符串

+ +

描述

+ +

toSource() 返回以下参数:

+ + + +

此方法通常由JavaScript内部调用,而不是在代码中显式调用。

+ +

规范

+ +

暂无标准, 在 JavaScript 1.3中实现.

+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.toSource")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/tostring/index.html new file mode 100644 index 0000000000..ce97ceafc5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/tostring/index.html @@ -0,0 +1,90 @@ +--- +title: Date.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/Date/toString +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toString +--- +
{{JSRef}}
+ +

toString() 方法返回一个字符串,表示该{{jsxref("Date")}}对象。

+ +
{{EmbedInteractiveExample("pages/js/date-tostring.html")}}
+ + + +

语法

+ +
dateObj.toString()
+ +

参数

+ +

+ +

描述

+ +

{{jsxref("Date")}}对象覆盖了 {{jsxref("Object")}} 对象的 toString() 方法;它不是继承自 {{jsxref("Object.prototype.toString()")}}。对于  {{jsxref("Date")}} 对象,toString() 方法返回一个表示该对象的字符串。

+ +

toString 方法总是返回一个美式英语日期格式的字符串。

+ +

当一个日期对象被用来作为文本值或用来进行字符串连接时,toString 方法会被自动调用。

+ +

toString() 是通用函数。如果不是{{jsxref("Date")}}实例,则 返回"Invalid Date"。

+ +

例子

+ +

例子: 使用 toString 方法

+ +

下例把一个{{jsxref("Date")}}对象的 toString 返回值赋给 myVar:

+ +
var x = new Date();
+myVar = x.toString(); // 把类似于下面格式的值赋给 myVar,
+// Fri Apr 26 2019 11:46:17 GMT+0800 (中国标准时间)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.9.5.2', 'Date.prototype.toLocaleTimeString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.tostring', 'Date.prototype.toString')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.tostring', 'Date.prototype.toString')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Date.toString")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/totimestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/totimestring/index.html new file mode 100644 index 0000000000..0a05806085 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/totimestring/index.html @@ -0,0 +1,73 @@ +--- +title: Date.prototype.toTimeString() +slug: Web/JavaScript/Reference/Global_Objects/Date/toTimeString +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toTimeString +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

toTimeString() 方法以人类易读形式返回一个日期对象时间部分的字符串,该字符串以美式英语格式化。

+ +
{{EmbedInteractiveExample("pages/js/date-totimestring.html")}}
+ + + +

语法

+ +
dateObj.toTimeString()
+ +

描述

+ +

{{jsxref("Global_Objects/Date", "Date")}} 对象的实例引用一个具体的时间点。 调用 {{jsxref("Date.toString", "toString")}} 方法以美式英语和人类易读的形式,返回日期对象的格式化字符串。在 SpiderMonkey 里,该字符串由日期部分(年月日)和其后的时间部分(时分秒和时区)组成。有时会需要获取时间部分的字符串,这可以由 toTimeString 方法完成。

+ +

The toTimeString method is especially useful because compliant engines implementing ECMA-262 may differ in the string obtained from toString for Date objects, as the format is implementation-dependent; simple string slicing approaches may not produce consistent results across multiple engines.

+ +

例子

+ +

例子:toTimeString 方法的简单使用

+ +
var d = new Date(1993, 6, 28, 14, 39, 7);
+
+println(d.toString());     // prints Wed Jul 28 1993 14:39:07 GMT-0600 (PDT)
+println(d.toTimeString()); // prints 14:39:07 GMT-0600 (PDT)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 3rd EditionStandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.4', 'Date.prototype.toTimeString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.totimestring', 'Date.prototype.toTimeString')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.toTimeString")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/toutcstring/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/toutcstring/index.html new file mode 100644 index 0000000000..4889075b1c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/toutcstring/index.html @@ -0,0 +1,76 @@ +--- +title: Date.prototype.toUTCString() +slug: Web/JavaScript/Reference/Global_Objects/Date/toUTCString +translation_of: Web/JavaScript/Reference/Global_Objects/Date/toUTCString +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

toUTCString() 方法把一个日期转换为一个字符串,使用UTC时区。

+ +
{{EmbedInteractiveExample("pages/js/date-toutcstring.html")}}
+ + + +

语法

+ +
dateObj.toUTCString()
+ +

返回值

+ +

返回使用UTC时区表示给定日期的字符串

+ +

 

+ +

描述

+ +

toUTCString 的返回值是一个使用UTC时区的易读格式字符串。返回值的格式可能随平台而变化。通常返回值是一个 RFC-1123 格式的时间戳,这是一个 RFC-822 时间戳的小幅更新版。

+ +

例子

+ +

例子:使用toUTCString

+ +
var today = new Date();
+var UTCstring = today.toUTCString();
+// Mon, 03 Jul 2006 21:44:38 GMT
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.3StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.42', 'Date.prototype.toUTCString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.toutcstring', 'Date.prototype.toUTCString')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.toUTCString")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/utc/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/utc/index.html new file mode 100644 index 0000000000..0be526200f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/utc/index.html @@ -0,0 +1,104 @@ +--- +title: Date.UTC() +slug: Web/JavaScript/Reference/Global_Objects/Date/UTC +tags: + - Date + - JavaScript + - Method +translation_of: Web/JavaScript/Reference/Global_Objects/Date/UTC +--- +
{{JSRef("Global_Objects", "Date")}}
+ +

Date.UTC() 方法接受的参数同日期构造函数接受最多参数时一样,返回从1970-1-1 00:00:00 UTC到指定日期的的毫秒数。

+ +
{{EmbedInteractiveExample("pages/js/date-utc.html")}}
+ + + +

语法

+ +
Date.UTC(year,month[,date[,hrs[,min[,sec{{mediawiki.external(',ms')}}]]]]) 
+ +

参数

+ +
+
year
+
1900 年后的某一年份。
+
month
+
0 到 11 之间的一个整数,表示月份。
+
date
+
1 到 31 之间的一个整数,表示某月当中的第几天。
+
hrs
+
0 到 23 之间的一个整数,表示小时。
+
min
+
0 到 59 之间的一个整数,表示分钟。
+
sec
+
0 到 59 之间的一个整数,表示秒。
+
ms
+
0 到 999 之间的一个整数,表示毫秒。
+
+ +

描述

+ +

UTC 方法接受以逗号隔开的日期参数,返回1970-1-1 00:00:00 UTC到指定的日期之间的毫秒数。

+ +

你应该指定一个完整格式的年份,如 1998。如果年份被指定为 0 到 99 之间,则该方法会将年份转换为 20 世纪的一个年份(即 1900 + year),例如,指定为 95, 则年份为 1995。

+ +

UTC 方法与 Date 有两点不同:

+ + + +

如果有一个指定的参数超出其合理范围,则 UTC 方法会通过更新其他参数直到该参数在合理范围内。例如,为月份指定 15,则年份将会加 1,然后月份将会使用 3。

+ +

由于 UTCDate(日期对象)的一个静态方法,所以应该在 Date 上直接调用,就像 Date.UTC(),而不要把它作为创建的日期对象的方法。

+ +

例子

+ +

例子:使用 Date.UTC

+ +

下面的语句使用 UTC 时间代替本地时间创建了一个日期对象。

+ +
var utcDate = new Date(Date.UTC(96, 11, 1, 0, 0, 0));
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.4.3', 'Date.UTC')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.utc', 'Date.UTC')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.UTC")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/valueof/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/valueof/index.html new file mode 100644 index 0000000000..9871342a43 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/date/valueof/index.html @@ -0,0 +1,86 @@ +--- +title: Date.prototype.valueOf() +slug: Web/JavaScript/Reference/Global_Objects/Date/valueOf +tags: + - Date + - JavaScript + - 原型 + - 参考 + - 方法 + - 日期 +translation_of: Web/JavaScript/Reference/Global_Objects/Date/valueOf +--- +
{{JSRef}}
+ +

valueOf() 方法返回一个 {{jsxref("Date")}} 对象的原始值。

+ +
{{EmbedInteractiveExample("pages/js/date-valueof.html")}}
+ +

语法

+ +
dateObj.valueOf()
+ +

返回值

+ +

从1970年1月1日0时0分0秒(UTC,即协调世界时)到该日期的毫秒数。

+ +

描述

+ +

valueOf 方法返回以数值格式表示的一个 Date 对象的原始值,从1970年1月1日0时0分0秒(UTC,即协调世界时)到该日期对象所代表时间的毫秒数。

+ +

该方法的功能和 {{jsxref("Date.prototype.getTime()")}} 方法一样。

+ +

该方法通常在 JavaScript 内部被调用,而不是在代码中显式调用。

+ +

例子

+ +

使用 valueOf()

+ +
var x = new Date(56, 6, 17);
+var myVar = x.valueOf();      // assigns -424713600000 to myVar
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.9.5.8', 'Date.prototype.valueOf')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-date.prototype.valueof', 'Date.prototype.valueOf')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-date.prototype.valueof', 'Date.prototype.valueOf')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.valueOf")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/decodeuri/index.html b/files/zh-cn/web/javascript/reference/global_objects/decodeuri/index.html new file mode 100644 index 0000000000..dfaaf7e104 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/decodeuri/index.html @@ -0,0 +1,121 @@ +--- +title: decodeURI() +slug: Web/JavaScript/Reference/Global_Objects/decodeURI +tags: + - JavaScript + - URI + - decodeURI() + - 统一资源标识符 +translation_of: Web/JavaScript/Reference/Global_Objects/decodeURI +--- +
{{jsSidebar("Objects")}}
+ +
+ +

decodeURI() 函数能解码由{{jsxref("encodeURI")}} 创建或其它流程得到的统一资源标识符(URI)。

+ +

{{EmbedInteractiveExample("pages/js/globalprops-decodeuri.html")}}

+ + + +

语法

+ +
decodeURI(encodedURI)
+ +

参数

+ +
+
encodedURI
+
一个完整的编码过的 URI
+
+ +

返回值

+ +

返回一个给定编码统一资源标识符(URI)的未编码版本的新字符串。

+ +

异常

+ +

encodedURI 包含无效字符序列时,引发{{jsxref("URIError")}}(“格式错误的URI序列”)异常。

+ +

描述

+ +

将已编码 URI 中所有能识别的转义序列转换成原字符,但不能解码那些不会被 {{jsxref("encodeURI")}} 编码的内容(例如 "#")。

+ +

示例

+ +

解码一个西里尔字母(Cyrillic)URL

+ +
decodeURI("https://developer.mozilla.org/ru/docs/JavaScript_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B");
+// "https://developer.mozilla.org/ru/docs/JavaScript_шеллы"
+
+ +

捕捉异常

+ +
try {
+  var a = decodeURI('%E0%A4%A');
+} catch(e) {
+  console.error(e);
+}
+
+// URIError: malformed URI sequence
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}初始定义
{{SpecName('ES5.1', '#sec-15.1.3.1', 'decodeURI')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-decodeuri-encodeduri', 'decodeURI')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-decodeuri-encodeduri', 'decodeURI')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.decodeURI")}}

+ +


+ 相关链接

+ +
+ + + +

+ +

+ +

+ +

diff --git a/files/zh-cn/web/javascript/reference/global_objects/decodeuricomponent/index.html b/files/zh-cn/web/javascript/reference/global_objects/decodeuricomponent/index.html new file mode 100644 index 0000000000..07070206e4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/decodeuricomponent/index.html @@ -0,0 +1,150 @@ +--- +title: decodeURIComponent() +slug: Web/JavaScript/Reference/Global_Objects/decodeURIComponent +tags: + - JavaScript + - URI + - 统一资源标识符 + - 解码 +translation_of: Web/JavaScript/Reference/Global_Objects/decodeURIComponent +--- +
{{jsSidebar("Objects")}}
+ +

decodeURIComponent() 方法用于解码由 {{jsxref("encodeURIComponent")}} 方法或者其它类似方法编码的部分统一资源标识符(URI)。

+ +

语法

+ +
decodeURIComponent(encodedURI)
+ +

参数

+ +
+
encodedURI
+
编码后的部分 URI
+
+ +

返回值

+ +

一个解码后的统一资源标识符(URI)字符串,处理前的URI经过了给定格式的编码。

+ +

异常

+ +

当该方法使用不当时,将会抛出一个{{jsxref("URIError")}}(格式错误的URI序列)异常。

+ +

描述

+ +

将已编码 URI 中所有能识别的转义序列转换成原字符。

+ +

示例

+ +

解码一个西里尔字母的URL

+ +
decodeURIComponent("JavaScript_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B");
+// "JavaScript_шеллы"
+
+ +

捕捉异常

+ +
try {
+  var a = decodeURIComponent('%E0%A4%A');
+} catch(e) {
+  console.error(e);
+}
+
+// URIError: malformed URI sequence
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}初始定义
{{SpecName('ES5.1', '#sec-15.1.3.2', 'decodeURIComponent')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-decodeuricomponent-encodeduricomponent', 'decodeURIComponent')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-decodeuricomponent-encodeduricomponent', 'decodeURIComponent')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基础功能{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础功能{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/global_objects/encodeuri/index.html b/files/zh-cn/web/javascript/reference/global_objects/encodeuri/index.html new file mode 100644 index 0000000000..8f3db7a445 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/encodeuri/index.html @@ -0,0 +1,170 @@ +--- +title: encodeURI() +slug: Web/JavaScript/Reference/Global_Objects/encodeURI +tags: + - JavaScript + - URI + - decodeURI + - encodeURI + - 统一资源定位符 +translation_of: Web/JavaScript/Reference/Global_Objects/encodeURI +--- +
{{jsSidebar("Objects")}}
+ +

encodeURI()  函数通过将特定字符的每个实例替换为一个、两个、三或四转义序列来对统一资源标识符 (URI) 进行编码 (该字符的 UTF-8 编码仅为四转义序列)由两个 "代理" 字符组成)。

+ +

语法

+ +
encodeURI(URI)
+ +

参数

+ +
+
URI
+
一个完整的URI.
+
+

返回值

+ +

    一个新字符串, 表示提供的字符串编码为统一资源标识符 (URI)。

+
+
+ +

描述

+ +

假定一个URI是完整的URI,那么无需对那些保留的并且在URI中有特殊意思的字符进行编码。

+ +
http://username:password@www.example.com:80/path/to/file.php?foo=316&bar=this+has+spaces#anchor
+ +

encodeURI 会替换所有的字符,但不包括以下字符,即使它们具有适当的UTF-8转义序列:

+ + + + + + + + + + + + + + + + + + + + +
类型包含
保留字符; , / ? : @ & = + $
非转义的字符字母 数字 - _ . ! ~ * ' ( )
数字符号#
+ +

请注意,encodeURI 自身无法产生能适用于HTTP GET 或 POST 请求的URI,例如对于 XMLHTTPRequests, 因为 "&", "+", 和 "=" 不会被编码,然而在 GET 和 POST 请求中它们是特殊字符。然而{{jsxref("encodeURIComponent")}}这个方法会对这些字符编码。

+ +

另外,如果试图编码一个非高-低位完整的代理字符,将会抛出一个 {{jsxref("URIError")}} 错误,例如:

+ +
// 编码高-低位完整字符 ok
+console.log(encodeURI('\uD800\uDFFF'));
+
+// 编码单独的高位字符抛出 "Uncaught URIError: URI malformed"
+console.log(encodeURI('\uD800'));
+
+// 编码单独的低位字符抛出 "Uncaught URIError: URI malformed"
+console.log(encodeURI('\uDFFF'));
+ +

并且需要注意,如果URL需要遵循较新的RFC3986标准,那么方括号是被保留的(给IPv6),因此对于那些没有被编码的URL部分(例如主机),可以使用下面的代码:

+ +
function fixedEncodeURI (str) {
+    return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']');
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}初始定义
{{SpecName('ES5.1', '#sec-15.1.3.3', 'encodeURI')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-encodeuri-uri', 'encodeURI')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-encodeuri-uri', 'encodeURI')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基础功能{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础功能{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/encodeuricomponent/index.html b/files/zh-cn/web/javascript/reference/global_objects/encodeuricomponent/index.html new file mode 100644 index 0000000000..d80cd457c9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/encodeuricomponent/index.html @@ -0,0 +1,144 @@ +--- +title: encodeURIComponent() +slug: Web/JavaScript/Reference/Global_Objects/encodeURIComponent +tags: + - JavaScript + - URI + - 统一资源标识符 +translation_of: Web/JavaScript/Reference/Global_Objects/encodeURIComponent +--- +
{{jsSidebar("Objects")}}
+ +

encodeURIComponent()函数通过将一个,两个,三个或四个表示字符的UTF-8编码的转义序列替换某些字符的每个实例来编码 URI (对于由两个“代理”字符组成的字符而言,将仅是四个转义序列) 。

+ +

{{EmbedInteractiveExample("pages/js/globalprops-encodeuricomponent.html","shorter")}}

+ +

语法

+ +
encodeURIComponent(str);
+ +

参数

+ +
+
str
+
String. URI 的组成部分。
+
+ +

返回值

+ +

原字串作为URI组成部分被被编码后的新字符串。

+ +

描述

+ +

encodeURIComponent 转义除了如下所示外的所有字符:

+ +
不转义的字符:
+    A-Z a-z 0-9 - _ . ! ~ * ' ( )
+ +

encodeURIComponent() 和 encodeURI 有以下几个不同点:

+ +
var set1 = ";,/?:@&=+$";  // 保留字符
+var set2 = "-_.!~*'()";   // 不转义字符
+var set3 = "#";           // 数字标志
+var set4 = "ABC abc 123"; // 字母数字字符和空格
+
+console.log(encodeURI(set1)); // ;,/?:@&=+$
+console.log(encodeURI(set2)); // -_.!~*'()
+console.log(encodeURI(set3)); // #
+console.log(encodeURI(set4)); // ABC%20abc%20123 (the space gets encoded as %20)
+
+console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24
+console.log(encodeURIComponent(set2)); // -_.!~*'()
+console.log(encodeURIComponent(set3)); // %23
+console.log(encodeURIComponent(set4)); // ABC%20abc%20123 (the space gets encoded as %20)
+ +

注意,如果试图编码一个非高-低位完整的代理字符,将会抛出一个 {{jsxref("URIError")}} 错误,例如:

+ +
// 高低位完整
+alert(encodeURIComponent('\uD800\uDFFF'));
+
+// 只有高位,将抛出"URIError: malformed URI sequence"
+alert(encodeURIComponent('\uD800'));
+
+// 只有低位,将抛出"URIError: malformed URI sequence"
+alert(encodeURIComponent('\uDFFF')); 
+ +

为了避免服务器收到不可预知的请求,对任何用户输入的作为URI部分的内容你都需要用encodeURIComponent进行转义。比如,一个用户可能会输入"Thyme &time=again"作为comment变量的一部分。如果不使用encodeURIComponent对此内容进行转义,服务器得到的将是comment=Thyme%20&time=again。请注意,"&"符号和"="符号产生了一个新的键值对,所以服务器得到两个键值对(一个键值对是comment=Thyme,另一个则是time=again),而不是一个键值对。

+ +

对于 application/x-www-form-urlencoded (POST) 这种数据方式,空格需要被替换成 '+',所以通常使用 encodeURIComponent 的时候还会把 "%20" 替换为 "+"。

+ +

为了更严格的遵循 RFC 3986(它保留 !, ', (, ), 和 *),即使这些字符并没有正式划定 URI 的用途,下面这种方式是比较安全的:

+ +
function fixedEncodeURIComponent (str) {
+  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
+    return '%' + c.charCodeAt(0).toString(16);
+  });
+}
+ +

示例

+ +

下面这个例子提供了 UTF-8 下 Content-DispositionLink 的服务器响应头信息的参数(例如 UTF-8 文件名):

+ +
var fileName = 'my file(2).txt';
+var header = "Content-Disposition: attachment; filename*=UTF-8''"
+             + encodeRFC5987ValueChars(fileName);
+
+console.log(header);
+// 输出 "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"
+
+
+function encodeRFC5987ValueChars (str) {
+    return encodeURIComponent(str).
+        // 注意,仅管 RFC3986 保留 "!",但 RFC5987 并没有
+        // 所以我们并不需要过滤它
+        replace(/['()]/g, escape). // i.e., %27 %28 %29
+        replace(/\*/g, '%2A').
+            // 下面的并不是 RFC5987 中 URI 编码必须的
+            // 所以对于 |`^ 这3个字符我们可以稍稍提高一点可读性
+            replace(/%(?:7C|60|5E)/g, unescape);
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}初始定义
{{SpecName('ES5.1', '#sec-15.1.3.4', 'encodeURIComponent')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-encodeuricomponent-uricomponent', 'encodeURIComponent')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-encodeuricomponent-uricomponent', 'encodeURIComponent')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.encodeURIComponent")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/columnnumber/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/columnnumber/index.html new file mode 100644 index 0000000000..cff8e92402 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/columnnumber/index.html @@ -0,0 +1,81 @@ +--- +title: Error.prototype.columnNumber +slug: Web/JavaScript/Reference/Global_Objects/Error/columnNumber +translation_of: Web/JavaScript/Reference/Global_Objects/Error/columnNumber +--- +
{{JSRef}} {{non-standard_header}}
+ +

columnNumber属性包含引发此错误的文件行中的列号。

+ +

例子

+ +

使用 columnNumber

+ +
var e = new Error('Could not parse input');
+throw e;
+console.log(e.columnNumber) // 0
+
+ +

规范

+ +

不属于任何规范的一部分. 非标准.

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/filename/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/filename/index.html new file mode 100644 index 0000000000..430cb738c2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/filename/index.html @@ -0,0 +1,85 @@ +--- +title: Error.prototype.fileName +slug: Web/JavaScript/Reference/Global_Objects/Error/fileName +translation_of: Web/JavaScript/Reference/Global_Objects/Error/fileName +--- +
{{JSRef}} {{non-standard_header}}
+ +

fileName 属性包含引发此错误的文件的路径.

+ +

描述

+ +

此非标准属性包含引发此错误的文件的路径. 如果从调试器上下文调用,例如Firefox Developer Tools,将会返回“debugger eval code”.

+ +

例子

+ +

使用 fileName

+ +
var e = new Error('Could not parse input');
+throw e;
+// e.fileName could look like "file:///C:/example.html"
+
+ +

规范

+ +

不属于任何规范的一部分. 非标准.

+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/index.html new file mode 100644 index 0000000000..27bd521d4e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/index.html @@ -0,0 +1,257 @@ +--- +title: Error +slug: Web/JavaScript/Reference/Global_Objects/Error +tags: + - Error + - Whoops! + - 参考 +translation_of: Web/JavaScript/Reference/Global_Objects/Error +--- +

{{JSRef}}

+ +

通过Error的构造器可以创建一个错误对象。当运行时错误产生时,Error的实例对象会被抛出。Error对象可用于用户自定义的异常的基础对象。下面列出了各种内建的标准错误类型。

+ +

语法

+ +
new Error([message[, fileName[,lineNumber]]])
+ +

参数

+ +
+
message
+
可选。人类可阅读的错误描述信息。
+
+ +
+
fileName {{non-standard_inline}}
+
可选。被创建的Error对象的fileName属性值。默认是调用Error构造器代码所在的文件 的名字。
+
+ +
+
lineNumber {{non-standard_inline}}
+
可选。被创建的Error对象的lineNumber属性值。默认是调用Error构造器代码所在的文件的行号
+
+ +

描述

+ +

当代码运行时的发生错误,会创建新的Error 对象,并将其抛出。

+ +

该页面描述了Error对象自身的使用,以及其构造函数的使用. 关于Error实例的内部属性和方法,请看 {{jsxref("Error.prototype")}}。

+ +

作为函数使用

+ +

当像函数一样使用 Error 时 -- 如果没有 {{jsxref("Operators/new", "new")}},它将返回一个 Error 对象。所以, 仅仅调用 Error 产生的结果与通过new 关键字构造 Error 对象生成的结果相同。 

+ +
// this:
+const x = Error('I was created using a function call!');
+​​​​// has the same functionality as this:
+const y = new Error('I was constructed via the "new" keyword!');
+ +

Error 类型

+ +

除了通用的Error构造函数外,JavaScript还有6个其他类型的错误构造函数。更多客户端异常,详见 Exception Handling Statements

+ +
+
{{jsxref("EvalError")}}
+
创建一个error实例,表示错误的原因:与 {{jsxref("Global_Objects/eval", "eval()")}} 有关。
+
{{jsxref("InternalError")}} {{non-standard_inline}}
+
创建一个代表Javascript引擎内部错误的异常抛出的实例。 如: "递归太多".
+
+ +
+
{{jsxref("RangeError", "RangeError")}}
+
创建一个error实例,表示错误的原因:数值变量或参数超出其有效范围
+
+ +
+
{{jsxref("ReferenceError")}}
+
创建一个error实例,表示错误的原因:无效引用。
+
+ +
+
{{jsxref("SyntaxError")}}
+
创建一个error实例,表示错误的原因:{{jsxref("Global_Objects/eval", "eval()")}}在解析代码的过程中发生的语法错误
+
+ +
+
{{jsxref("TypeError")}}
+
创建一个error实例,表示错误的原因:变量或参数不属于有效类型。
+
+ +
+
{{jsxref("URIError")}}
+
创建一个error实例,表示错误的原因:给 {{jsxref("Global_Objects/encodeURI", "encodeURI()")}}或  {{jsxref("Global_Objects/decodeURI", "decodeURl()")}}传递的参数无效。
+
+ +

属性

+ +
+
{{jsxref("Error.prototype")}}
+
允许添加属性到Error实例。
+
+ +

方法

+ +

全局Error对象自身不包含任何方法,但从原型链中继承了一些方法.

+ +

Error 实例

+ +
+

{{page('en-US/docs/JavaScript/Reference/Global_Objects/Error/prototype', 'Description')}}

+ +

属性

+ +

{{page('en-US/docs/JavaScript/Reference/Global_Objects/Error/prototype', 'Properties')}}

+ +

方法

+ +

{{page('en-US/docs/JavaScript/Reference/Global_Objects/Error/prototype', 'Methods')}}

+
+ +

例子

+ +

抛出一个基本错误

+ +

通常你会使用{{jsxref("Statements/throw", "throw")}}关键字来抛出你创建的Error对象。可以使用 {{jsxref("Statements/try...catch", "try...catch")}} 结构来处理异常:

+ +
try {
+    throw new Error("Whoops!");
+} catch (e) {
+    alert(e.name + ": " + e.message);
+}
+
+ +

处理一个特定错误

+ +

你可以通过判断异常的类型来特定处理某一类的异常,即判断 {{jsxref("Object.prototype.constructor", "constructor")}} 属性,当使用现代Javascript引擎时,可使用{{jsxref("Operators/instanceof", "instanceof")}} 关键字:

+ +
try {
+    foo.bar();
+} catch (e) {
+    if (e instanceof EvalError) {
+        alert(e.name + ": " + e.message);
+    } else if (e instanceof RangeError) {
+        alert(e.name + ": " + e.message);
+    }
+    // ... etc
+}
+
+ +

自定义异常类型

+ +

你可能希望自定义基于Error的异常类型,使得你能够 throw new MyError() 并可以使用 instanceof MyError 来检查某个异常的类型. 这种需求的通用解决方法如下.

+ +
+

注意,在FireFox中抛出自定义类型的异常会显示不正确的行号和文件名。

+
+ +

参考 "What's a good way to extend Error in JavaScript?" discussion on Stackoverflow.

+ +
// Create a new object, that prototypally inherits from the Error constructor.
+function MyError(message) {
+  this.name = 'MyError';
+  this.message = message || 'Default Message';
+  this.stack = (new Error()).stack;
+}
+MyError.prototype = Object.create(Error.prototype);
+MyError.prototype.constructor = MyError;
+
+try {
+  throw new MyError();
+} catch (e) {
+  console.log(e.name);     // 'MyError'
+  console.log(e.message);  // 'Default Message'
+}
+
+try {
+  throw new MyError('custom message');
+} catch (e) {
+  console.log(e.name);     // 'MyError'
+  console.log(e.message);  // 'custom message'
+}
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.11', 'Error')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-error-objects', 'Error')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-error-objects', 'Error')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{Compat("javascript.builtins.Error")}}
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/linenumber/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/linenumber/index.html new file mode 100644 index 0000000000..a7b1ecd375 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/linenumber/index.html @@ -0,0 +1,54 @@ +--- +title: Error.prototype.lineNumber +slug: Web/JavaScript/Reference/Global_Objects/Error/lineNumber +tags: + - JavaScript + - 属性 + - 错误 +translation_of: Web/JavaScript/Reference/Global_Objects/Error/lineNumber +--- +
{{JSRef}} {{non-standard_header}}
+ +

lineNumber 属性的值为抛出错误的代码在其源文件中所在的行号。

+ +

示例

+ +

使用 lineNumber

+ +
var e = new Error('Could not parse input');
+throw e;
+console.log(e.lineNumber) // 2
+
+ +

监听 error 事件的示例

+ +
window.addEventListener('error', function(e) {
+  console.log(e.lineNumber); // 5
+});
+var e = new Error('Could not parse input');
+throw e;
+
+ +

这不是一个标准化的属性,缺乏广泛的支持。参见下面的浏览器兼容性表格。

+ +

规范

+ +

非标准化属性。不属于任何规范。

+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Error.lineNumber")}}

+
+
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/message/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/message/index.html new file mode 100644 index 0000000000..92ba4e16c1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/message/index.html @@ -0,0 +1,110 @@ +--- +title: Error.prototype.message +slug: Web/JavaScript/Reference/Global_Objects/Error/message +translation_of: Web/JavaScript/Reference/Global_Objects/Error/message +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+ +

概述

+ +

message 属性是有关错误信息,人类易读的(human-readable)描述。

+ +

描述

+ +

如果该属性已经被设置,则该属性包含了错误的一个简短描述。SpiderMonkey 大量应用 message 属性在异常方面。 message 属性结合 {{jsxref("Error.prototype.name", "name")}} 属性一起被  {{jsxref("Error.prototype.toString()")}} 方法用来创建错误的字符串形式。

+ +

默认情况下,message 属性是一个空字符串,但是可以通过指定一段信息作为 {{jsxref("Error", "Error constructor")}} 的第一个参数创建一个实例来改变该属性值。

+ +

示例

+ +

例子:抛出一个自定义错误

+ +
var e = new Error("Could not parse input"); // e.message is "Could not parse input"
+throw e;
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.11.4.3', 'Error.prototype.message')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-error.prototype.message', 'Error.prototype.message')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/name/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/name/index.html new file mode 100644 index 0000000000..85eba29c8a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/name/index.html @@ -0,0 +1,110 @@ +--- +title: Error.prototype.name +slug: Web/JavaScript/Reference/Global_Objects/Error/name +translation_of: Web/JavaScript/Reference/Global_Objects/Error/name +--- +

{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}

+ +

概述

+ +

name 属性表示error类型的名称.初始值为"Error".

+ +

描述

+ +

默认情况下,{{jsxref("Error")}}对象的name属性值为"Error".name属性和{{jsxref("Error.prototype.message", "message")}}属性一起,通过调用{{jsxref("Error.prototype.toString()")}}方法,会作为最后异常信息的字符串表示.

+ +

示例

+ +

例子: 抛出一个自定义错误

+ +
var e = new Error("Malformed input"); // e.name默认是"Error"
+
+e.name = "ParseError";                // 修改之后,e.toString()会成为下面这样的字符串
+throw e;                              // "ParseError: Malformed input"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.11.4.2', 'Error.prototype.name')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-error.prototype.name', 'Error.prototype.name')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/prototype/index.html new file mode 100644 index 0000000000..aea7d132d2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/prototype/index.html @@ -0,0 +1,161 @@ +--- +title: Error.prototype +slug: Web/JavaScript/Reference/Global_Objects/Error/prototype +tags: + - Error + - JavaScript + - Property + - 参考 + - 属性 +translation_of: Web/JavaScript/Reference/Global_Objects/Error +--- +
+

{{JSRef}}

+ +

Error.prototype 属性代表 {{jsxref("Error")}} 的构造器。

+ +

{{js_property_attributes(0, 0, 0)}}

+
+ +

描述

+ +

所有 {{jsxref("Global_Objects/Error", "Error")}} 与 {{jsxref("Global_Objects/Error", "非标准Error", "#Error_types", 1)}} 的实例都继承自 Error.prototype。同所有构造器函数一样,你可以在构造器的 prototype 上添加属性或者方法,使其在所有该构造器的实例上生效。

+ +

属性

+ +

标准属性

+ +
+
Error.prototype.constructor
+
实例原型的构造函数。
+
{{jsxref("Error.prototype.message")}}
+
错误信息。
+
{{jsxref("Error.prototype.name")}}
+
错误名。
+
+ +

厂商特定扩展属性

+ +
{{non-standard_header}}
+ +

Microsoft

+ +
+
{{jsxref("Error.prototype.description")}}
+
错误描述,与 {{jsxref("Error.prototype.message", "message")}} 相似。
+
{{jsxref("Error.prototype.number")}}
+
错误码。
+
+ +

Mozilla

+ +
+
{{jsxref("Error.prototype.fileName")}}
+
产生该错误的文件名。
+
{{jsxref("Error.prototype.lineNumber")}}
+
产生该错误的行号。
+
{{jsxref("Error.prototype.columnNumber")}}
+
产生该错误的列号。
+
{{jsxref("Error.prototype.stack")}}
+
错误堆栈。
+
+ +

方法

+ +
+
{{jsxref("Error.prototype.toSource()")}} {{non-standard_inline}}
+
返回一个包含特定 {{jsxref("Error")}} 对象的源代码字符串,你可以用该值新建一个新的对象,重写自 {{jsxref("Object.prototype.toSource()")}} 方法。
+
{{jsxref("Error.prototype.toString()")}}
+
返回一个表示该对象的字符串,重写自 {{jsxref("Object.prototype.toString()")}} 方法。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.11.3.1', 'Error')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-error.prototype', 'Error')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-error.prototype', 'Error')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/stack/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/stack/index.html new file mode 100644 index 0000000000..b828e71662 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/stack/index.html @@ -0,0 +1,126 @@ +--- +title: Error.prototype.stack +slug: Web/JavaScript/Reference/Global_Objects/Error/Stack +tags: + - JavaScript + - 原型 + - 参考 + - 属性 + - 错误 +translation_of: Web/JavaScript/Reference/Global_Objects/Error/Stack +--- +
{{JSRef}} {{non-standard_header}}
+ +

{{jsxref("Error")}}对象作为一个非标准的栈属性提供了一种函数追踪方式。无论这个函数被被调用,处于什么模式,来自于哪一行或者哪个文件,有着什么样的参数。这个栈产生于最近一次调用最早的那次调用,返回原始的全局作用域调用

+ +

描述

+ +

每个步骤都会被分为单独的一行以这个函数的名字作为开始(如果不是一个来自于全局作用域的调用),然后通过一个@符号标记一个文件的位置(尤其是当一个函数构造错误并且作为错误被抛出,并且如果能定位到这个文件的位置,那么会使用冒号显示行号。(提示){{jsxref("Error")}}对象在错误跑出时同样能处理并渲染出文件名,行号和列号属性(但是仅仅限于错误。而不是追踪他的路径)

+ +

注意这是Firefox定义的格式,并没有标准的定义。但是Safari 6+ 和 Opera 12-定义了一种非常相似的格式。其他使用JavaScript V8引擎的浏览器(例如Chrome, Opera 15+,安卓浏览器)和IE 10+,定义了一种不同的格式(可参见 error.stack 文档)

+ +

堆栈中的参数值: Firefox 14版本之前是 ({{bug("744842")}})函数名会随着参数值会在添加@符号之前被立即转换成用圆括号包裹的string类型。然而对象或者数组等其他类型似乎会被转换成"[object Object]"并且这种格式不能回退到之前实际上的对象,而纯值会被渲染(或许这种在Firefox14中仍有这种可能,使用arguments.callee.caller.arguments更加简单。因为函数名可以使用arguments.callee.caller.name渲染)。"undefined"被显示为"(void 0)"不过要注意的是如果是字符串类型的参数会直接以类似"@", "(", ")"格式通过编译(或者是包含在文件名中)。你不能简单的依赖这些将它分成多个组件,但是,对于Firefox14及以后的版本来说,这些都不是问题

+ +

不同的浏览器会在不同时期设置这个值。例如,Firefox在创建{{jsxref("Error")}}对象时设置它,然而PhantomJS是在当且仅当它抛出 {{jsxref("Error")}}时, 并且MSDN docs 似乎也实现了PhantomJS的方式。

+ +

示例

+ +

下面这段html代码展示了stack 属性的使用方法

+ +
<!DOCTYPE HTML>
+<meta charset="UTF-8">
+<title>Stack Trace Example</title>
+<body>
+<script>
+function trace() {
+  try {
+    throw new Error('myError');
+  }
+  catch(e) {
+    alert(e.stack);
+  }
+}
+function b() {
+  trace();
+}
+function a() {
+  b(3, 4, '\n\n', undefined, {});
+}
+a('first call, firstarg');
+</script>
+
+
+ +

假设上面这段代码被保存在Windows系统下的 C:\example.html在处理过程中抛出如下所示的错误信息

+ +

Firefox 30及以上版本的浏览器会包含以列号为开始 ({{bug("762556")}}):

+ +
trace@file:///C:/example.html:9:17
+b@file:///C:/example.html:16:13
+a@file:///C:/example.html:19:13
+@file:///C:/example.html:21:9
+ +

Firefox 14 to Firefox 29:

+ +
trace@file:///C:/example.html:9
+b@file:///C:/example.html:16
+a@file:///C:/example.html:19
+@file:///C:/example.html:21
+ +

Firefox 13及更早版本的浏览器会抛出如下信息:

+ +
Error("myError")@:0
+trace()@file:///C:/example.html:9
+b(3,4,"\n\n",(void 0),[object Object])@file:///C:/example.html:16
+a("first call, firstarg")@file:///C:/example.html:19
+@file:///C:/example.html:21
+ +

Stack of eval'ed code

+ +

Firefox30以{{geckoRelease("30")}}格式开头,Function() 和 eval() 调用产生的错误代码堆栈,现在在调用内部通过行号和列号以更加详细的格式向我们展示出来。函数调用显示为"> Function" 而 eval调用则是 "> eval"这样。下面来看这个{{bug("332176")}}.

+ +
try {
+  new Function('throw new Error()')();
+} catch (e) {
+  console.log(e.stack);
+}
+
+// anonymous@file:///C:/example.html line 7 > Function:1:1
+// @file:///C:/example.html:7:6
+
+
+try {
+  eval("eval('FAIL')");
+} catch (x) {
+  console.log(x.stack);
+}
+
+// @file:///C:/example.html line 7 > eval line 1 > eval:1:1
+// @file:///C:/example.html line 7 > eval:1:1
+// @file:///C:/example.html:7:6
+
+ +

你也可以使用//# sourceURL 命名eval源的指令。 也可以查看在 Debugger文档中的Debug eval 源blog post博客 。

+ +

规范

+ +

不属于任何规范,没有标准规范。

+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Error.stack")}}

+
+
+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/tosource/index.html new file mode 100644 index 0000000000..89273b1f32 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/tosource/index.html @@ -0,0 +1,53 @@ +--- +title: Error.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/Error/toSource +translation_of: Web/JavaScript/Reference/Global_Objects/Error/toSource +--- +
{{JSRef}} {{non-standard_header}}
+ +

toSource() 方法返回可以计算出到相同错误的代码。

+ +

语法

+ +
e.toSource()
+ +

返回值

+ +

一个包含错误源代码的字符串

+ +

描述

+ +

调用一个{{jsxref("Error")}}实例的toSource方法(包括 NativeErrors)将返回包含错误源代码的字符串。 这个字符串可以被评估创建一个(大约)相等的对象。当然,包含源字符串遵循的结构{{ jsxref("Error")}} 构造函数。例如:

+ +
(newname(message ,fileName,lineNumber))
+
+ +

这些属性对应于错误实例的相应属性。

+ +
+

提示:  需要注意到,在创建该字符串时,toSource方法所使用的属性是可变的,并且可能无法准确地反映用于创建错误实例的函数或实际发生错误的文件名或行号。

+
+ +

规范

+ +

不属于任何规范. 应用于 in JavaScript 1.3.

+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Error.toSource")}}

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/tostring/index.html new file mode 100644 index 0000000000..a32f0919d3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/error/tostring/index.html @@ -0,0 +1,129 @@ +--- +title: Error.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/Error/toString +translation_of: Web/JavaScript/Reference/Global_Objects/Error/toString +--- +
+ {{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+

概述

+

toString() 方法返回一个指定的错误对象(Error object)的字符串表示。

+

语法

+
e.toString();
+

描述

+

{{jsxref("Error")}} 对象覆盖了 {{jsxref("Object.prototype.toString()")}} 方法。该方法实现如下:(假定 ObjectString 没有被更改):

+
Error.prototype.toString = function()
+{
+  "use strict";
+
+  var obj = Object(this);
+  if (obj !== this)
+    throw new TypeError();
+
+  var name = this.name;
+  name = (name === undefined) ? "Error" : String(name);
+
+  var msg = this.message;
+  msg = (msg === undefined) ? "" : String(msg);
+
+  if (name === "")
+    return msg;
+  if (msg === "")
+    return name;
+
+  return name + ": " + msg;
+};
+
+

示例

+
var e = new Error("fatal error");
+print(e.toString()); // "Error: fatal error"
+
+e.name = undefined;
+print(e.toString()); // "Error: fatal error"
+
+e.name = "";
+print(e.toString()); // "fatal error"
+
+e.message = undefined;
+print(e.toString()); // "Error"
+
+e.name = "hello";
+print(e.toString()); // "hello"
+
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition.StandardInitial definition.
+ Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-15.11.4.4', 'Error.prototype.toString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-error.prototype.tostring', 'Error.prototype.toString')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/escape/index.html b/files/zh-cn/web/javascript/reference/global_objects/escape/index.html new file mode 100644 index 0000000000..295bf14331 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/escape/index.html @@ -0,0 +1,126 @@ +--- +title: escape() +slug: Web/JavaScript/Reference/Global_Objects/escape +translation_of: Web/JavaScript/Reference/Global_Objects/escape +--- +
+
+
{{jsSidebar("Objects")}} {{deprecated_header}}
+
+
+ +

概览

+ +

废弃的 escape() 方法生成新的由十六进制转义序列替换的字符串. 使用 {{jsxref("Global_Objects/encodeURI", "encodeURI")}} 或 {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} 代替.

+ +

语法

+ +
escape(str)
+ +

参数

+ +
+
str
+
待编码的字符串.
+
+ +

描述

+ +

escape 函数是全局对象的属性. 特色字符如: @*_+-./ 被排除在外.

+ +

字符的16进制格式值,当该值小于等于0xFF时,用一个2位转移序列: %xx 表示. 大于的话则使用4位序列:%uxxxx 表示.

+ +

示例

+ +
escape("abc123");     // "abc123"
+escape("äöü");        // "%E4%F6%FC"
+escape("ć");          // "%u0107"
+
+// special characters
+escape("@*_+-./");    // "@*_+-./"
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-B.2.1', 'escape')}}{{Spec2('ES5.1')}}Defined in the (informative) Compatibility Annex B
{{SpecName('ES6', '#sec-escape-string', 'escape')}}{{Spec2('ES6')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

其他链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/eval/index.html b/files/zh-cn/web/javascript/reference/global_objects/eval/index.html new file mode 100644 index 0000000000..4189e29d72 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/eval/index.html @@ -0,0 +1,319 @@ +--- +title: eval() +slug: Web/JavaScript/Reference/Global_Objects/eval +tags: + - JavaScript + - eval + - 参考 +translation_of: Web/JavaScript/Reference/Global_Objects/eval +--- +
{{jsSidebar("Objects")}}
+ +

eval() 函数会将传入的字符串当做 JavaScript 代码进行执行。

+ +
{{EmbedInteractiveExample("pages/js/globalprops-eval.html")}}
+ + + +

语法

+ +
eval(string)
+ +

参数

+ +
+
string
+
一个表示 JavaScript 表达式、语句或一系列语句的字符串。表达式可以包含变量与已存在对象的属性。
+
+ +

返回值

+ +

返回字符串中代码的返回值。如果返回值为空,则返回 {{jsxref("undefined")}}。

+ +

描述

+ +

eval() 是全局对象的一个函数属性。

+ +

eval() 的参数是一个字符串。如果字符串表示的是表达式,eval() 会对表达式进行求值。如果参数表示一个或多个 JavaScript 语句,那么eval() 就会执行这些语句。不需要用 eval() 来执行一个算术表达式:因为 JavaScript 可以自动为算术表达式求值。

+ +

如果你以字符串的形式构造了算术表达式,那么可以在后面用 eval()对它求值。例如,假设你有一个变量 x,您可以通过将表达式的字符串值(例如 3 * x + 2)赋值给一个变量,然后在你的代码后面的其他地方调用 eval(),来推迟涉及 x 的表达式的求值。

+ +

如果 eval() 的参数不是字符串, eval() 会将参数原封不动地返回。在下面的例子中,String 构造器被指定,而 eval() 返回了 String 对象而不是执行字符串。

+ +
eval(new String("2 + 2")); // 返回了包含"2 + 2"的字符串对象
+eval("2 + 2");             // returns 4
+
+ +

你可以使用一些通用的方法来绕过这个限制,例如使用 toString()

+ +
var expression = new String("2 + 2");
+eval(expression.toString());
+
+ +

如果你间接的使用 eval(),比如通过一个引用来调用它,而不是直接的调用 eval。 从 ECMAScript 5 起,它工作在全局作用域下,而不是局部作用域中。这就意味着,例如,下面的代码的作用声明创建一个全局函数,并且 eval 中的这些代码在执行期间不能在被调用的作用域中访问局部变量。

+ +
function test() {
+  var x = 2, y = 4;
+  console.log(eval('x + y'));  // 直接调用,使用本地作用域,结果是 6
+  var geval = eval; // 等价于在全局作用域调用
+  console.log(geval('x + y')); // 间接调用,使用全局作用域,throws ReferenceError 因为`x`未定义
+  (0, eval)('x + y'); // 另一个间接调用的例子
+​}
+ +

永远不要使用 eval

+ +

eval() 是一个危险的函数, 它使用与调用者相同的权限执行代码。如果你用 eval() 运行的字符串代码被恶意方(不怀好意的人)修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。更重要的是,第三方代码可以看到某一个 eval() 被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的 {{jsxref("Global_Objects/Function", "Function")}} 就不容易被攻击。

+ +

eval() 通常比其他替代方法更慢,因为它必须调用 JS 解释器,而许多其他结构则可被现代 JS 引擎进行优化。

+ +

此外,现代JavaScript解释器将javascript转换为机器代码。 这意味着任何变量命名的概念都会被删除。 因此,任意一个eval的使用都会强制浏览器进行冗长的变量名称查找,以确定变量在机器代码中的位置并设置其值。 另外,新内容将会通过 eval() 引进给变量, 比如更改该变量的类型,因此会强制浏览器重新执行所有已经生成的机器代码以进行补偿。 但是,(谢天谢地)存在一个非常好的eval替代方法:只需使用 window.Function。 这有个例子方便你了解如何将eval()的使用转变为Function()

+ +

使用eval的糟糕代码:

+ +
function looseJsonParse(obj){
+    return eval("(" + obj + ")");
+}
+console.log(looseJsonParse(
+   "{a:(4-1), b:function(){}, c:new Date()}"
+))
+
+ +

 不用eval的更好的代码:

+ +
function looseJsonParse(obj){
+    return Function('"use strict";return (' + obj + ')')();
+}
+console.log(looseJsonParse(
+   "{a:(4-1), b:function(){}, c:new Date()}"
+))
+
+
+ +

比较上面的两个代码片段,两个代码片段似乎是以相同的方式工作,但再想一想:eval的这个代码的速度要慢得多。 注意c: new Date()在执行体中。 在没有eval的函数中,对象在全局范围内被用来进行计算,因此浏览器可以放心的假设Date是来自window.Date的而不是一个名为Date的局部变量。 然而,在使用eval()的代码中,浏览器不能假设这一点,因为如果您的代码是下面这个:

+ +
function Date(n){
+    return ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"][n%7 || 0];
+}
+function looseJsonParse(obj){
+    return eval("(" + obj + ")");
+}
+console.log(looseJsonParse(
+   "{a:(4-1), b:function(){}, c:new Date()}"
+))
+
+ +

因此,在eval()版本的代码中,浏览器被迫进行高代价的查找调用以检查是否存在名为Date()的任何局部变量。 与Function()相比,这是非常低效的。

+ +

在类似的情况下,如果您确实希望能够从Function()内部的代码调用Date函数,该怎么办? 你应该躲避并退回到eval()吗? 绝对不是,永远不要这么做。 而是尝试下面的方法。

+ +
function Date(n){
+    return ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"][n%7 || 0];
+}
+function runCodeWithDateFunction(obj){
+    return Function('"use strict";return (' + obj + ')')()(
+        Date
+    );
+}
+console.log(runCodeWithDateFunction(
+   "function(Date){ return Date(5) }"
+))
+
+ +

由于三重嵌套函数,上面的代码似乎效率低下,但让我们分析一下上述有效方法的好处:

+ +

1.它使得传递给runCodeWithDateFunction的字符串中的代码更少。

+ +

2.函数调用开销很小,使得代码尺寸小得多,值得获益

+ +

3. Function()更容易让你的代码利用特性修饰"use strict";

+ +

4.代码不使用eval(),使其比其他方式快几个数量级。

+ +

最后,我们来看看简化版。 使用如上所示的Function(),您可以更有效地缩小传递给runCodeWithDateFunction的代码字符串,因为函数参数名称也可以缩小,如下面的缩小代码所示。

+ +
console.log(Function('"use strict";return(function(a){return a(5)})')()(function(a){
+return"Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" ")[a%7||0]}));
+ +

对于常见用例,eval()Function()还有更安全(而且更快!)的替代方案。

+ +

访问成员属性

+ +

你不应该去使用 eval() 来将属性名字转化为属性。考虑下面的这个例子,被访问对象的属性在它被执行之前都会未知的。这里可以用 eval 处理:

+ +
var obj = { a: 20, b: 30 };
+var propName = getPropName(); // 返回 "a" 或 "b"
+
+eval( 'var result = obj.' + propsName )
+ +

但是,这里并不是必须得使用 eval() 。事实上,这里并不建议这样使用。可以使用 属性访问器 进行代替,它更快、更安全:

+ +
var obj = { a: 20, b: 30 }
+var propName = getPropName(); // 返回 "a" 或 "b"
+var result = obj[ propName ]; // obj[ "a" ] 与 obj.a 等价
+ +

你还可以使用这个方法去访问子代的属性。如下:

+ +
var obj = {a: {b: {c: 0}}};
+var propPath = getPropPath(); // 例如返回 "a.b.c"
+
+eval( 'var result = obj.' + propPath )
+
+ +

这里,可以通过分割属性路径、循环遍历不同的属性,来避免 eval()

+ +
function getDescendantProp(obj, desc) {
+  var arr = desc.split('.');
+  while (arr.length) {
+    obj = obj[arr.shift()];
+  }
+  return obj;
+}
+
+var obj = {a: {b: {c: 0}}};
+var propPath = getPropPath(); // 例如返回 "a.b.c"
+var result = getDescendantProp(obj, propPath);
+ +

同样的方法也可实现设置子代的属性值:

+ +
function setDescendantProp(obj, desc, value) {
+  var arr = desc.split('.');
+  while (arr.length > 1) {
+    obj = obj[arr.shift()];
+  }
+  return obj[arr[0]] = value;
+}
+
+var obj = {a: {b: {c: 0}}};
+var propPath = getPropPath();  // 例如,返回 "a.b.c"
+var result = setDescendantProp(obj, propPath, 1);  // a.b.c 值为 1
+ +

使用函数而非代码段

+ +

JavaScript 拥有 first-class functions,这意味着你可以将函数直接作为参数传递给其他接口,将他们保存在变量中或者对象的属性中,等等。很多DOM的API都用这种思路进行设计,你也可以(或者应该)这样子设计你的代码:

+ +
// 代替 setTimeout(" ... ", 1000) 写法:
+setTimeout(function() { ... }, 1000);
+
+// 代替 elt.setAttribute("onclick", "...") 写法:
+elt.addEventListener('click', function() { ... } , false);
+ +

闭包 也有助于创建参数化函数而不用连接字符串。

+ +

解析 JSON(将字符串转化为 JavaScript 对象)

+ +

如果你在调用 eval() 传入的字符串参数中包含数据(如:一个数组“[1,2,3]”)而不是代码,你应该考虑将其转换为 JSON 对象,这允许你用JavaScript语法的子集来表示数据。在扩展中下载JSON和JavaScript

+ +

提示:因为 JSON 语法子集相对于 JavaScript 语法子集比较有局限性,很多在 JavaScript 中可用的特性在 JSON 中就不起作用了。比如,后缀逗号在 JSON 中不支持,并且对象中的属性名在 JSON 中必须用引号括起来。请务必使用 JSON 序列化方法来生成稍后将被解析为 JSON 的字符串。

+ +

尽量传递数据而非代码

+ +

例如,设计为抓取网页内容的扩展,可能会在XPath中定义抓取规则,而不是在 JavaScript 代码中。

+ +

以有限权限运行代码

+ +

如果你必须执行这段代码, 应考虑以更低的权限运行。此建议主要适用于扩展和 XUL 应用程序,可以使用 Components.utils.evalInSandbox 做到降低权限。

+ +

例子

+ +

使用 eval

+ +

在下面的代码中,两种包含了 eval() 的声明都返回了 42。第一种是对字符串 "x + y + 1" 求值;第二种是对字符串 "42" 求值。

+ +
var x = 2;
+var y = 39;
+var z = "42";
+eval("x + y + 1"); // returns 42
+eval(z);           // returns 42
+
+ +

使用 eval 执行一串 JavaScript 语句

+ +

下面的例子使用 eval() 来执行 str 字符串。这个字符串包含了如果 x 等于5,就打开一个Alert 对话框并对 z 赋值 42,否则就对 z 赋值 0 的 JavaScript 语句。 当第二个声明被执行,eval() 将会令字符串被执行,并最终返回赋值给 z 的 42。

+ +
var x = 5;
+var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z = 0;";
+
+console.log('z is ', eval(str));
+ +

如果您定义了多个值,则会返回最后一个值。

+ +
var x = 5;
+var str = "if (x == 5) {console.log('z is 42'); z = 42; x = 420; } else z = 0;";
+
+console.log('x is ', eval(str)); // z is 42  x is 420
+
+ +

返回值

+ +

eval 返回最后一个表达式的值。

+ +
var str = 'if ( a ) { 1 + 1; } else { 1 + 2; }';
+var a = true;
+var b = eval(str);  // returns 2
+
+console.log('b is : ' + b);
+
+a = false;
+b = eval(str);  // returns 3
+
+console.log('b is : ' + b);
+ +

eval 中函数作为字符串被定义需要“(”和“)”作为前缀和后缀

+ +
var fctStr1 = 'function a() {}'
+var fctStr2 = '(function a() {})'
+var fct1 = eval(fctStr1)  // 返回undefined
+var fct2 = eval(fctStr2)  // 返回一个函数
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.1.2.1', 'eval')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-eval-x', 'eval')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-eval-x', 'eval')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.eval")}}

+ +

Firefox 相关

+ + + +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/evalerror/index.html b/files/zh-cn/web/javascript/reference/global_objects/evalerror/index.html new file mode 100644 index 0000000000..85eebfa1ce --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/evalerror/index.html @@ -0,0 +1,116 @@ +--- +title: EvalError +slug: Web/JavaScript/Reference/Global_Objects/EvalError +translation_of: Web/JavaScript/Reference/Global_Objects/EvalError +--- +
{{JSRef}}
+ +

本对象代表了一个关于 eval 函数的错误.此异常不再会被JavaScript抛出,但是EvalError对象仍然保持兼容性.

+ +

语法

+ +
new EvalError([message[, fileName[, lineNumber]]])
+ +

参数

+ +
+
message
+
可选参数.人类可阅读的关于错误的描述.
+
+ +
+
fileName(非标准)
+
可选参数.代码中导致异常的文件的文件名.
+
+ +
+
lineNumber(非标准)
+
可选参数.代码中导致异常的代码的行号.
+
+ +

属性

+ +
+
prototype
+
允许向EvalError对象中添加自定义属性.
+
+ +

方法

+ +

全局的EvalError对象本身不包含任何方法, 然而它通过原型链继承了一些方法.

+ +

EvalError 实例

+ +

属性

+ +

{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/EvalError/prototype', 'Properties')}}

+ +

方法

+ +

{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/EvalError/prototype', 'Methods')}}

+ +

例子

+ +

EvalError 不在当前ECMAScript规范中使用,因此不会被运行时抛出. 但是对象本身仍然与规范的早期版本向后兼容.

+ +

创建 EvalError

+ +
try {
+  throw new EvalError('Hello', 'someFile.js', 10);
+} catch (e) {
+  console.log(e instanceof EvalError); // true
+  console.log(e.message);              // "Hello"
+  console.log(e.name);                 // "EvalError"
+  console.log(e.fileName);             // "someFile.js"
+  console.log(e.lineNumber);           // 10
+  console.log(e.columnNumber);         // 0
+  console.log(e.stack);                // "@Scratchpad/2:2:9\n"
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ES3')}}{{Spec2('ES3')}}初始定义.
{{SpecName('ES5.1', '#sec-15.11.6.1', 'EvalError')}}{{Spec2('ES5.1')}}本规范中未使用. 为了保持向后兼容.
{{SpecName('ES6', '#sec-native-error-types-used-in-this-standard-evalerror', 'EvalError')}}{{Spec2('ES6')}}本规范中未使用. 为了保持向后兼容.
{{SpecName('ESDraft', '#sec-native-error-types-used-in-this-standard-evalerror', 'EvalError')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.EvalError")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/evalerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/evalerror/prototype/index.html new file mode 100644 index 0000000000..1ea7e10e86 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/evalerror/prototype/index.html @@ -0,0 +1,84 @@ +--- +title: EvalError.prototype +slug: Web/JavaScript/Reference/Global_Objects/EvalError/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/EvalError +--- +
{{JSRef}}
+ +

EvalError.prototype 属性是 {{jsxref("EvalError")}} 原型构造函数.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Description

+ +

{{jsxref("EvalError")}} 全部实例都继承自EvalError.prototype. 你可以通过prototype去添加方法和属性.

+ +

Properties

+ +
+
EvalError.prototype.constructor
+
指定创建实例原型的函数.
+
{{jsxref("Error.prototype.message", "EvalError.prototype.message")}}
+
错误信息. 从 ECMA-262 开始 {{jsxref("EvalError")}} 提供 message (继承自{{jsxref("Error.prototype.message")}})属性, 详见 SpiderMonkey.
+
{{jsxref("Error.prototype.name", "EvalError.prototype.name")}}
+
错误名称.继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "EvalError.prototype.fileName")}}
+
引发错误的文件路径. 继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "EvalError.prototype.lineNumber")}}
+
引发错误所在行.继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "EvalError.prototype.columnNumber")}}
+
引发错误所在的列. 继承自{{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "EvalError.prototype.stack")}}
+
堆栈.继承自 {{jsxref("Error")}}.
+
+ +

Methods

+ +

虽然 {{jsxref("EvalError")}} 自己的属性方法较少, 但是通过原型链继承了很多有用的方法.

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}初代.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}定义为NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}定义为NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}定义为NativeError.prototype.
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.EvalError")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/finalizationregistry/index.html b/files/zh-cn/web/javascript/reference/global_objects/finalizationregistry/index.html new file mode 100644 index 0000000000..10e720eb80 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/finalizationregistry/index.html @@ -0,0 +1,153 @@ +--- +title: FinalizationRegistry +slug: Web/JavaScript/Reference/Global_Objects/FinalizationRegistry +tags: + - FinalizationRegistry + - GC + - 垃圾回收 +translation_of: Web/JavaScript/Reference/Global_Objects/FinalizationRegistry +--- +
{{JSRef}}
+ +

FinalizationRegistry 对象可以让你在对象被垃圾回收时请求一个回调。

+ +

描述

+ +

FinalizationRegistry 提供了这样的一种方法:当一个在注册表中注册的对象被回收时,请求在某个时间点上调用一个清理回调。(清理回调有时被称为 finalizer )。

+ +
+

注意: 清理回调不应被用于必要的程序逻辑。详情请看清理回调的注意事项

+
+ +

你在回调中创建了如下的 registry:

+ +
const registry = new FinalizationRegistry(heldValue => {
+  // ....
+});
+
+ +

然后,你可以通过调用`register`方法,注册任何你想要清理回调的对象,传入该对象和*所含的值*。

+ +
registry.register(theObject, "some value");
+
+ +

The registry does not keep a strong reference to the object, as that would defeat the purpose (if the registry held it strongly, the object would never be reclaimed).

+ +

If theObject is reclaimed, your cleanup callback may be called at some point with the held value you provided for it ("some value" in the above). The held value can be any value you like: a primitive or an object, even undefined. If the held value is an object, the registry keeps a strong reference to it (so it can pass it to your cleanup callback later).

+ +

If you might want to unregister an object later, you pass a third value, which is the unregistration token you'll use later when calling the registry's unregister function to unregister the object. The registry only keeps a weak reference to the unregister token.

+ +

It's common to use the object itself as the unregister token, which is just fine:

+ +
registry.register(theObject, "some value", theObject);
+// ...some time later, if you don't care about `theObject` anymore...
+registry.unregister(theObject);
+
+ +

It doesn't have to be the same object, though; it can be a different one:

+ +
registry.register(theObject, "some value", tokenObject);
+// ...some time later, if you don't care about `theObject` anymore...
+registry.unregister(tokenObject);
+
+ +

Constructor

+ +
+
{{jsxref("FinalizationRegistry/FinalizationRegistry", "FinalizationRegistry()")}}
+
Creates a new FinalizationRegistry object.
+
+ +

Instance methods

+ +
+
{{jsxref("FinalizationRegistry.register", "FinalizationRegistry.prototype.register()")}}
+
Registers an object with the registry in order to get a cleanup callback when/if the object is garbage-collected.
+
{{jsxref("FinalizationRegistry.unregister", "FinalizationRegistry.prototype.unregister()")}}
+
Unregisters an object from the registry.
+
+ +

Avoid where possible

+ +

Correct use of FinalizationRegistry takes careful thought, and it's best avoided if possible. It's also important to avoid relying on any specific behaviors not guaranteed by the specification. When, how, and whether garbage collection occurs is down to the implementation of any given JavaScript engine. Any behavior you observe in one engine may be different in another engine, in another version of the same engine, or even in a slightly different situation with the same version of the same engine. Garbage collection is a hard problem that JavaScript engine implementers are constantly refining and improving their solutions to.

+ +

Here are some specific points that the authors of the WeakRef proposal that FinalizationRegistry is part of included in its explainer document:

+ +
+

Garbage collectors are complicated. If an application or library depends on GC cleaning up a FinalizationRegistry or calling a finalizer [cleanup callback] in a timely, predictable manner, it's likely to be disappointed: the cleanup may happen much later than expected, or not at all. Sources of variability include:

+ + +
+ +

Notes on cleanup callbacks

+ +

Some notes on cleanup callbacks:

+ + + +

Examples

+ +

Creating a new registry

+ +

You create the registry passing in the callback:

+ +
const registry = new FinalizationRegistry(heldValue => {
+  // ....
+});
+
+ +

Registering objects for cleanup

+ +

Then you register any objects you want a cleanup callback for by calling the `register` method, passing in the object and a *held value* for it:

+ +
registry.register(theObject, "some value");
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('WeakRefs', '#sec-finalization-registry-objects', 'FinalizationRegistry')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.FinalizationRegistry")}}

+ +

See also

+ + + +
+
+
diff --git a/files/zh-cn/web/javascript/reference/global_objects/float32array/index.html b/files/zh-cn/web/javascript/reference/global_objects/float32array/index.html new file mode 100644 index 0000000000..393c5e4c2d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/float32array/index.html @@ -0,0 +1,261 @@ +--- +title: Float32Array +slug: Web/JavaScript/Reference/Global_Objects/Float32Array +tags: + - JavaScript + - TypeArray + - TypeArrays + - 构造函数 +translation_of: Web/JavaScript/Reference/Global_Objects/Float32Array +--- +
{{JSRef}}
+ +

Float32Array 类型数组代表的是平台字节顺序为32位的浮点数型数组(对应于 C 浮点数据类型) 。 如果需要控制字节顺序, 使用 {{jsxref("DataView")}} 替代。其内容初始化为0。一旦建立起来,你可以使用这个对象的方法对其元素进行操作,或者使用标准数组索引语法 (使用方括号)。

+ +

语法

+ +
new Float32Array(length);
+new Float32Array(typedArray);
+new Float32Array(object);
+new Float32Array(buffer [, byteOffset [, length]]);
+ +

更多的语法信息和参数,参见 TypedArray

+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "Float32Array.BYTES_PER_ELEMENT")}}
+
返回元素字节数。  Float32Array的情况下返回4。
+
Float32Array.length
+
长度属性的值为 3。关于其实际长度(元素数量)参见{{jsxref("TypedArray.prototype.length", "Float32Array.prototype.length")}}。
+
{{jsxref("TypedArray.name", "Float32Array.name")}}
+
返回构造函数名字的字符串值。在 Float32Array 类型的情况下为:"Float32Array"。
+
{{jsxref("TypedArray.prototype", "Float32Array.prototype")}}
+
 TypedArray对象的原型。
+
+ +

方法

+ +
+
{{jsxref("TypedArray.from", "Float32Array.from()")}}
+
从一个类数组对象或可遍历对象创建一个新的Float32Array。参见 {{jsxref("Array.from()")}}。
+
{{jsxref("TypedArray.of", "Float32Array.of()")}}
+
用可变数量的参数创建一个新的Float32Array。 参见 {{jsxref("Array.of()")}}。
+
+ +

Float32Array 属性

+ +

所有的Float32Array对象都继承自 {{jsxref("TypedArray.prototype", "%TypedArray%.prototype")}}。

+ +

特性

+ +
+
Float32Array.prototype.constructor
+
返回创建这个实例原型的函数。 这是Float32Array 默认的构造函数。
+
{{jsxref("TypedArray.prototype.buffer", "Float32Array.prototype.buffer")}} {{readonlyInline}}
+
返回这个Float32Array引用的{{jsxref("ArrayBuffer")}}。构造时已固定,所以是只读的。
+
{{jsxref("TypedArray.prototype.byteLength", "Float32Array.prototype.byteLength")}} {{readonlyInline}}
+
返回从Float32Array的{{jsxref("ArrayBuffer")}}开头开始长度 (以字节为单位) 。构造时已固定,所以是只读的。
+
{{jsxref("TypedArray.prototype.byteOffset", "Float32Array.prototype.byteOffset")}} {{readonlyInline}}
+
返回从Float32Array的{{jsxref("ArrayBuffer")}}开头开始的偏移量 (以字节为单位) 。构造时已固定,所以是只读的。
+
{{jsxref("TypedArray.prototype.length", "Float32Array.prototype.length")}} {{readonlyInline}}
+
返回Float32Array中的元素个数。构造时已固定,所以是只读的。
+
+ +

方法

+ +
+
{{jsxref("TypedArray.copyWithin", "Float32Array.prototype.copyWithin()")}}
+
从数组复制元素。参见{{jsxref("Array.prototype.copyWithin()")}}。
+
{{jsxref("TypedArray.entries", "Float32Array.prototype.entries()")}}
+
返回一个包含数组中每个元素键值对的数组遍历器对象。参见{{jsxref("Array.prototype.entries()")}}。
+
{{jsxref("TypedArray.every", "Float32Array.prototype.every()")}}
+
检测是否所有元素都能通过给定函数的测试。参见{{jsxref("Array.prototype.every()")}}。
+
{{jsxref("TypedArray.fill", "Float32Array.prototype.fill()")}}
+
用一个静态值填充给定的起始位置。 参见{{jsxref("Array.prototype.fill()")}}。
+
{{jsxref("TypedArray.filter", "Float32Array.prototype.filter()")}}
+
创建一个新数组,数据为原数组中所有能让给入函数返回true的元素。参见{{jsxref("Array.prototype.filter()")}}。
+
{{jsxref("TypedArray.find", "Float32Array.prototype.find()")}}
+
返回满足测试函数的值,如果没有找到,返回undefined。 参见{{jsxref("Array.prototype.find()")}}。
+
{{jsxref("TypedArray.findIndex", "Float32Array.prototype.findIndex()")}}
+
返回满足测试函数的值的位置,如果没有找到,返回-1。参见{{jsxref("Array.prototype.findIndex()")}}。
+
{{jsxref("TypedArray.forEach", "Float32Array.prototype.forEach()")}}
+
以每个元素为参数各调用一次函数。参见{{jsxref("Array.prototype.forEach()")}}。
+
{{jsxref("TypedArray.includes", "Float32Array.prototype.includes()")}} {{experimental_inline}}
+
判断是否包含某个元素,返回truefalse。参见{{jsxref("Array.prototype.includes()")}}。
+
{{jsxref("TypedArray.indexOf", "Float32Array.prototype.indexOf()")}}
+
返回数组中等于给定值的元素的第一个(最小)位置, 没有找到则返回-1。参见{{jsxref("Array.prototype.indexOf()")}}。
+
{{jsxref("TypedArray.join", "Float32Array.prototype.join()")}}
+
合并所有数组元素到一个字符串中。 参见{{jsxref("Array.prototype.join()")}}。
+
{{jsxref("TypedArray.keys", "Float32Array.prototype.keys()")}}
+
返回一个包含数组中所有索引的数组遍历器。 参见{{jsxref("Array.prototype.keys()")}}。
+
{{jsxref("TypedArray.lastIndexOf", "Float32Array.prototype.lastIndexOf()")}}
+
返回数组中等于给定值的元素的最后(最大)位置, 没有找到则返回-1。参见{{jsxref("Array.prototype.lastIndexOf()")}}。
+
{{jsxref("TypedArray.map", "Float32Array.prototype.map()")}}
+
创建一个新的数组,数据由原数组每个元素依次传入给定函数后返回的值组成。参见{{jsxref("Array.prototype.map()")}}。
+
{{jsxref("TypedArray.move", "Float32Array.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
+
{{jsxref("TypedArray.copyWithin", "Float32Array.prototype.copyWithin()")}}以前的一个非标准版本。
+
{{jsxref("TypedArray.reduce", "Float32Array.prototype.reduce()")}}
+
传入一个函数作为累加器,从左到右遍历,最终得到一个值。 参见{{jsxref("Array.prototype.reduce()")}}。
+
{{jsxref("TypedArray.reduceRight", "Float32Array.prototype.reduceRight()")}}
+
传入一个函数作为累加器,从右到左遍历,最终得到一个值。参见{{jsxref("Array.prototype.reduceRight()")}}。
+
{{jsxref("TypedArray.reverse", "Float32Array.prototype.reverse()")}}
+
反转数组元素的顺序 — 第一个变为最后一个, 最后一个变为第一个。参见{{jsxref("Array.prototype.reverse()")}}。
+
{{jsxref("TypedArray.set", "Float32Array.prototype.set()")}}
+
从给定的数组存入多个数值。
+
{{jsxref("TypedArray.slice", "Float32Array.prototype.slice()")}}
+
提取数组的一部分并且返回一个新数组。参见{{jsxref("Array.prototype.slice()")}}。
+
{{jsxref("TypedArray.some", "Float32Array.prototype.some()")}}
+
如果数组中至少有一个元素满足测试函数的要求则返回true。参见{{jsxref("Array.prototype.some()")}}。
+
{{jsxref("TypedArray.sort", "Float32Array.prototype.sort()")}}
+
对数组元素进行排序并返回数组。参见{{jsxref("Array.prototype.sort()")}}。
+
{{jsxref("TypedArray.subarray", "Float32Array.prototype.subarray()")}}
+
从给定的起始位置返回一个新的Float32Array
+
{{jsxref("TypedArray.values", "Float32Array.prototype.values()")}}
+
返回一个包含所有数组元素的数组遍历器对象。 参见{{jsxref("Array.prototype.values()")}}。
+
{{jsxref("TypedArray.toLocaleString", "Float32Array.prototype.toLocaleString()")}}
+
返回一个代表数组和其元素的本地化格式字符串。参见{{jsxref("Array.prototype.toLocaleString()")}}。
+
{{jsxref("TypedArray.toString", "Float32Array.prototype.toString()")}}
+
返回一个代表数组和它的元素的字符串。参见{{jsxref("Array.prototype.toString()")}}。
+
{{jsxref("TypedArray.@@iterator", "Float32Array.prototype[@@iterator]()")}}
+
返回一个新的包含数组元素的数组迭代器对象。
+
+ +

例子

+ +
// From a length
+var float32 = new Float32Array(2);
+float32[0] = 42;
+console.log(float32[0]); // 42
+console.log(float32.length); // 2
+console.log(float32.BYTES_PER_ELEMENT); // 4
+
+// From an array
+var arr = new Float32Array([21,31]);
+console.log(arr[1]); // 31
+
+// From another TypedArray
+var x = new Float32Array([21, 31]);
+var y = new Float32Array(x);
+console.log(y[0]); // 21
+
+// From an ArrayBuffer
+var buffer = new ArrayBuffer(16);
+var z = new Float32Array(buffer, 0, 4);
+
+ +

 

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}被ECMAScript 6取代
{{SpecName('ES6', '#table-49', 'TypedArray constructors')}}{{Spec2('ES6')}}在ECMA中初始定义,另外规定需要使用new。
{{SpecName('ESDraft', '#table-49', 'TypedArray constructors')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基础支持7.0{{CompatGeckoDesktop(2)}}1011.65.1
需要new{{CompatUnknown}}{{CompatGeckoDesktop(44)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础支持4.0{{CompatVersionUnknown}}{{CompatGeckoMobile(2)}}1011.64.2
需要new{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile(44)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

一致性提示

+ +

从ECMAScript 2015 (ES6)开始, Float32Array构造函数需要用一个{{jsxref("Operators/new", "new")}}操作符来构造。现在直接把Float32Array构造函数当函数调用而不使用new,会抛出一个{{jsxref("TypeError")}}。

+ +
var dv = Float32Array([1, 2, 3]);
+// TypeError: calling a builtin Float32Array constructor
+// 不允许不使用new
+ +
var dv = new Float32Array([1, 2, 3]);
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/float64array/index.html b/files/zh-cn/web/javascript/reference/global_objects/float64array/index.html new file mode 100644 index 0000000000..8c08d222d8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/float64array/index.html @@ -0,0 +1,259 @@ +--- +title: Float64Array +slug: Web/JavaScript/Reference/Global_Objects/Float64Array +tags: + - JavaScript + - TypeArray + - TypeArrays + - 构造函数 +translation_of: Web/JavaScript/Reference/Global_Objects/Float64Array +--- +
{{JSRef}}
+ +

Float64Array 类型数组代表的是平台字节顺序为64位的浮点数型数组(对应于 C 浮点数据类型) 。 如果需要控制字节顺序, 使用 {{jsxref("DataView")}} 替代。其内容初始化为0。一旦建立起来,你可以使用这个对象的方法对其元素进行操作,或者使用标准数组索引语法 (使用方括号)。

+ +

?语法 

+ +
new Float64Array(length);
+new Float64Array(typedArray);
+new Float64Array(object);
+new Float64Array(buffer [, byteOffset [, length]]);
+ +

更多的语法信息和参数,参见 TypedArray.

+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "Float64Array.BYTES_PER_ELEMENT")}}
+
返回元素字节数。  Float64Array的情况下返回8。
+
Float64Array.length
+
长度属性的值为 3。关于其实际长度(元素数量)参见 {{jsxref("TypedArray.prototype.length", "Float64Array.prototype.length")}}。
+
{{jsxref("TypedArray.name", "Float64Array.name")}}
+
返回构造函数名字的字符串值。在 Float64Array 类型的情况下为:"Float64Array"。
+
{{jsxref("TypedArray.prototype", "Float64Array.prototype")}}
+
TypedArray对象的原型。
+
+ +

方法

+ +
+
{{jsxref("TypedArray.from", "Float64Array.from()")}}
+
从一个类数组对象或可遍历对象创建一个新的Float64Array。参见 {{jsxref("Array.from()")}}。
+
{{jsxref("TypedArray.of", "Float64Array.of()")}}
+
用可变数量的参数创建一个新的Float64Array。 参见 {{jsxref("Array.of()")}}。
+
+ +

Float64Array 属性

+ +

所有的Float64Array对象都继承自 {{jsxref("TypedArray.prototype", "%TypedArray%.prototype")}}。

+ +

特性

+ +
+
Float64Array.prototype.constructor
+
返回创建这个实例原型的函数。 这是Float64Array 默认的构造函数。
+
{{jsxref("TypedArray.prototype.buffer", "Float64Array.prototype.buffer")}} {{readonlyInline}}
+
返回这个Float64Array引用的 {{jsxref("ArrayBuffer")}}。构造时已固定,所以是只读的。
+
{{jsxref("TypedArray.prototype.byteLength", "Float64Array.prototype.byteLength")}} {{readonlyInline}}
+
返回从Float64Array的{{jsxref("ArrayBuffer")}}开头开始长度 (以字节为单位) 。构造时已固定,所以是只读的。
+
{{jsxref("TypedArray.prototype.byteOffset", "Float64Array.prototype.byteOffset")}} {{readonlyInline}}
+
返回从Float64Array的{{jsxref("ArrayBuffer")}}开头开始的偏移量 (以字节为单位) 。构造时已固定,所以是只读的。
+
{{jsxref("TypedArray.prototype.length", "Float64Array.prototype.length")}} {{readonlyInline}}
+
返回Float64Array中的元素个数。构造时已固定,所以是只读的。
+
+ +

方法

+ +
+
{{jsxref("TypedArray.copyWithin", "Float64Array.prototype.copyWithin()")}}
+
从数组复制元素。参见{{jsxref("Array.prototype.copyWithin()")}}。
+
{{jsxref("TypedArray.entries", "Float64Array.prototype.entries()")}}
+
返回一个包含数组中每个元素键值对的数组遍历器对象。参见{{jsxref("Array.prototype.entries()")}}。
+
{{jsxref("TypedArray.every", "Float64Array.prototype.every()")}}
+
检测是否所有元素都能通过给定函数的测试。参见{{jsxref("Array.prototype.every()")}}。
+
{{jsxref("TypedArray.fill", "Float64Array.prototype.fill()")}}
+
用一个静态值填充给定的起始位置。 参见{{jsxref("Array.prototype.fill()")}}。
+
{{jsxref("TypedArray.filter", "Float64Array.prototype.filter()")}}
+
创建一个新数组,数据为原数组中所有能让给入函数返回true的元素。参见{{jsxref("Array.prototype.filter()")}}。
+
{{jsxref("TypedArray.find", "Float64Array.prototype.find()")}}
+
返回满足测试函数的值,如果没有找到,返回undefined。 参见{{jsxref("Array.prototype.find()")}}。
+
{{jsxref("TypedArray.findIndex", "Float64Array.prototype.findIndex()")}}
+
返回满足测试函数的值的位置,如果没有找到,返回-1。参见{{jsxref("Array.prototype.findIndex()")}}。
+
{{jsxref("TypedArray.forEach", "Float64Array.prototype.forEach()")}}
+
以每个元素为参数各调用一次函数。参见{{jsxref("Array.prototype.forEach()")}}。
+
{{jsxref("TypedArray.includes", "Float64Array.prototype.includes()")}} {{experimental_inline}}
+
判断是否包含某个元素,返回truefalse。参见{{jsxref("Array.prototype.includes()")}}。
+
{{jsxref("TypedArray.indexOf", "Float64Array.prototype.indexOf()")}}
+
返回数组中等于给定值的元素的第一个(最小)位置, 没有找到则返回-1。参见{{jsxref("Array.prototype.indexOf()")}}。
+
{{jsxref("TypedArray.join", "Float64Array.prototype.join()")}}
+
合并所有数组元素到一个字符串中。 参见{{jsxref("Array.prototype.join()")}}。
+
{{jsxref("TypedArray.keys", "Float64Array.prototype.keys()")}}
+
返回一个包含数组中所有索引的数组遍历器。 参见{{jsxref("Array.prototype.keys()")}}。
+
{{jsxref("TypedArray.lastIndexOf", "Float64Array.prototype.lastIndexOf()")}}
+
返回数组中等于给定值的元素的最后(最大)位置, 没有找到则返回-1。参见{{jsxref("Array.prototype.lastIndexOf()")}}。
+
{{jsxref("TypedArray.map", "Float64Array.prototype.map()")}}
+
创建一个新的数组,数据由原数组每个元素依次传入给定函数后返回的值组成。参见{{jsxref("Array.prototype.map()")}}。
+
{{jsxref("TypedArray.move", "Float64Array.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
+
{{jsxref("TypedArray.copyWithin", "Float64Array.prototype.copyWithin()")}}以前的一个非标准版本。
+
{{jsxref("TypedArray.reduce", "Float64Array.prototype.reduce()")}}
+
传入一个函数作为累加器,从左到右遍历,最终得到一个值。 参见{{jsxref("Array.prototype.reduce()")}}。
+
{{jsxref("TypedArray.reduceRight", "Float64Array.prototype.reduceRight()")}}
+
传入一个函数作为累加器,从右到左遍历,最终得到一个值。参见{{jsxref("Array.prototype.reduceRight()")}}。
+
{{jsxref("TypedArray.reverse", "Float64Array.prototype.reverse()")}}
+
反转数组元素的顺序 — 第一个变为最后一个, 最后一个变为第一个。参见{{jsxref("Array.prototype.reverse()")}}。
+
{{jsxref("TypedArray.set", "Float64Array.prototype.set()")}}
+
从给定的数组存入多个数值。
+
{{jsxref("TypedArray.slice", "Float64Array.prototype.slice()")}}
+
提取数组的一部分并且返回一个新数组。参见{{jsxref("Array.prototype.slice()")}}。
+
{{jsxref("TypedArray.some", "Float64Array.prototype.some()")}}
+
如果数组中至少有一个元素满足测试函数的要求则返回true。参见{{jsxref("Array.prototype.some()")}}。
+
{{jsxref("TypedArray.sort", "Float64Array.prototype.sort()")}}
+
对数组元素进行排序并返回数组。参见{{jsxref("Array.prototype.sort()")}}。
+
{{jsxref("TypedArray.subarray", "Float64Array.prototype.subarray()")}}
+
从给定的起始位置返回一个新的Float64Array 。
+
{{jsxref("TypedArray.values", "Float64Array.prototype.values()")}}
+
返回一个包含所有数组元素的数组遍历器对象。 参见{{jsxref("Array.prototype.values()")}}。
+
{{jsxref("TypedArray.toLocaleString", "Float64Array.prototype.toLocaleString()")}}
+
返回一个代表数组和其元素的本地化格式字符串。参见{{jsxref("Array.prototype.toLocaleString()")}}。
+
{{jsxref("TypedArray.toString", "Float64Array.prototype.toString()")}}
+
返回一个代表数组和它的元素的字符串。参见{{jsxref("Array.prototype.toString()")}}。
+
{{jsxref("TypedArray.@@iterator", "Float64Array.prototype[@@iterator]()")}}
+
返回一个新的包含数组元素的数组迭代器对象。
+
+ +

例子

+ +
// From a length
+var float64 = new Float64Array(2);
+float64[0] = 42;
+console.log(float64[0]); // 42
+console.log(float64.length); // 2
+console.log(float64.BYTES_PER_ELEMENT); // 8
+
+// From an array
+var arr = new Float64Array([21,31]);
+console.log(arr[1]); // 31
+
+// From another TypedArray
+var x = new Float64Array([21, 31]);
+var y = new Float64Array(x);
+console.log(y[0]); // 21
+
+// From an ArrayBuffer
+var buffer = new ArrayBuffer(32);
+var z = new Float64Array(buffer, 0, 4);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
?规范?状态?注释
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}被ECMAScript 6取代。
{{SpecName('ES6', '#table-49', 'TypedArray constructors')}}{{Spec2('ES6')}}在ECMA中初始定义,另外规定需要使用new。
{{SpecName('ESDraft', '#table-49', 'TypedArray constructors')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基础支持7.0{{CompatGeckoDesktop(2)}}1011.65.1
需要用new{{CompatUnknown}}{{CompatGeckoDesktop(44)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础支持4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile(2) }}1011.64.2
需要用new{{CompatUnknown}}{{CompatUnknown}}{{ CompatGeckoMobile(44) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

一致性提示

+ +

从ECMAScript 2015 (ES6)开始, Float32Array构造函数需要用一个{{jsxref("Operators/new", "new")}}操作符来构造。现在直接把Float32Array构造函数当函数调用而不使用new,会抛出一个{{jsxref("TypeError")}}。

+ +
var dv = Float64Array([1, 2, 3]);
+// TypeError: calling a builtin Float64Array constructor
+// 不允许不使用new
+ +
var dv = new Float64Array([1, 2, 3]);
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/apply/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/apply/index.html new file mode 100644 index 0000000000..de53da11e7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/apply/index.html @@ -0,0 +1,219 @@ +--- +title: Function.prototype.apply() +slug: Web/JavaScript/Reference/Global_Objects/Function/apply +tags: + - Function + - JavaScript + - Method +translation_of: Web/JavaScript/Reference/Global_Objects/Function/apply +--- +
{{JSRef}}
+ +

apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

+ +
注意:call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组
+ +
{{EmbedInteractiveExample("pages/js/function-apply.html")}}
+ + + +

语法

+ +
func.apply(thisArg, [argsArray])
+ +

参数

+ +
+
thisArg
+
必选的。在 func 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于{{jsxref("Strict_mode", "非严格模式", "", 1)}}下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
+
argsArray
+
可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 {{jsxref("null")}} 或  {{jsxref("undefined")}},则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。 {{anch("Browser_compatibility", "浏览器兼容性")}} 请参阅本文底部内容。
+
+ +

返回值

+ +

调用有指定this值和参数的函数的结果。

+ +

描述

+ +

在调用一个存在的函数时,你可以为其指定一个 this 对象。 this 指当前对象,也就是正在调用这个函数的对象。 使用 apply, 你可以只写一次这个方法然后在另一个对象中继承它,而不用在新对象中重复写该方法。

+ +

apply 与 {{jsxref("Function.call", "call()")}} 非常相似,不同之处在于提供参数的方式。apply 使用参数数组而不是一组参数列表。apply 可以使用数组字面量(array literal),如 fun.apply(this, ['eat', 'bananas']),或数组对象, 如  fun.apply(this, new Array('eat', 'bananas'))

+ +

你也可以使用 {{jsxref("Functions/arguments", "arguments")}}对象作为 argsArray 参数。 arguments 是一个函数的局部变量。 它可以被用作被调用对象的所有未指定的参数。 这样,你在使用apply函数的时候就不需要知道被调用对象的所有参数。 你可以使用arguments来把所有的参数传递给被调用对象。 被调用对象接下来就负责处理这些参数。

+ +

从 ECMAScript 第5版开始,可以使用任何种类的类数组对象,就是说只要有一个 length 属性和(0..length-1)范围的整数属性。例如现在可以使用 {{domxref("NodeList")}} 或一个自己定义的类似 {'length': 2, '0': 'eat', '1': 'bananas'} 形式的对象。

+ +
+

需要注意:Chrome 14 以及 Internet Explorer 9 仍然不接受类数组对象。如果传入类数组对象,它们会抛出异常。

+
+ +

示例

+ +

用 apply 将数组各项添加到另一个数组

+ +

我们可以使用push将元素追加到数组中。由于push接受可变数量的参数,所以也可以一次追加多个元素。

+ +

但是,如果push的参数是数组,它会将该数组作为单个元素添加,而不是将这个数组内的每个元素添加进去,因此我们最终会得到一个数组内的数组。如果不想这样呢?concat符合我们的需求,但它并不是将元素添加到现有数组,而是创建并返回一个新数组。 然而我们需要将元素追加到现有数组......那么怎么做好?难道要写一个循环吗?别当然不是!

+ +

apply正派上用场!

+ +
var array = ['a', 'b'];
+var elements = [0, 1, 2];
+array.push.apply(array, elements);
+console.info(array); // ["a", "b", 0, 1, 2]
+
+ +

使用apply和内置函数

+ +

对于一些需要写循环以便历数组各项的需求,我们可以用apply完成以避免循环。

+ +

下面是示例,我们将用Math.max/Math.min求得数组中的最大/小值。

+ +
/* 找出数组中最大/小的数字 */
+var numbers = [5, 6, 2, 3, 7];
+
+/* 使用Math.min/Math.max以及apply 函数时的代码 */
+var max = Math.max.apply(null, numbers); /* 基本等同于 Math.max(numbers[0], ...) 或 Math.max(5, 6, ..) */
+var min = Math.min.apply(null, numbers);
+
+/* 对比:简单循环算法 */
+max = -Infinity, min = +Infinity;
+
+for (var i = 0; i < numbers.length; i++) {
+  if (numbers[i] > max)
+    max = numbers[i];
+  if (numbers[i] < min)
+    min = numbers[i];
+}
+ +

注意:如果按上面方式调用apply,有超出JavaScript引擎参数长度上限的风险。一个方法传入过多参数(比如一万个)时的后果在不同JavaScript 引擎中表现不同。(JavaScriptCore引擎中有被硬编码的 参数个数上限:65536)。这是因为此限制(实际上也是任何用到超大栈空间的行为的自然表现)是不明确的。一些引擎会抛出异常,更糟糕的是其他引擎会直接限制传入到方法的参数个数,导致参数丢失。比如:假设某个引擎的方法参数上限为4(实际上限当然要高得多), 这种情况下,上面的代码执行后, 真正被传递到 apply的参数为 5, 6, 2, 3 ,而不是完整的数组。

+ +

如果你的参数数组可能非常大,那么推荐使用下面这种混合策略:将数组切块后循环传入目标方法:

+ +
function minOfArray(arr) {
+  var min = Infinity;
+  var QUANTUM = 32768;
+
+  for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
+    var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
+    min = Math.min(submin, min);
+  }
+
+  return min;
+}
+
+var min = minOfArray([5, 6, 2, 3, 7]);
+
+ +

使用apply来链接构造器

+ +

你可以使用apply来链接一个对象构造器,类似于Java。在接下来的例子中我们会创建一个全局Function 对象的construct方法 ,来使你能够在构造器中使用一个类数组对象而非参数列表。

+ +
Function.prototype.construct = function (aArgs) {
+  var oNew = Object.create(this.prototype);
+  this.apply(oNew, aArgs);
+  return oNew;
+};
+
+ +
+

注意: 上面使用的Object.create()方法相对来说比较新。另一种可选的方法,请考虑如下替代方法:

+ +

Using {{jsxref("Object/__proto__", "Object.__proto__")}}:

+ +
Function.prototype.construct = function (aArgs) {
+  var oNew = {};
+  oNew.__proto__ = this.prototype;
+  this.apply(oNew, aArgs);
+  return oNew;
+};
+ +

使用闭包:

+ +
Function.prototype.construct = function(aArgs) {
+  var fConstructor = this, fNewConstr = function() {
+    fConstructor.apply(this, aArgs);
+  };
+  fNewConstr.prototype = fConstructor.prototype;
+  return new fNewConstr();
+};
+ +

使用 Function 构造器:

+ +
Function.prototype.construct = function (aArgs) {
+  var fNewConstr = new Function("");
+  fNewConstr.prototype = this.prototype;
+  var oNew = new fNewConstr();
+  this.apply(oNew, aArgs);
+  return oNew;
+};
+
+ +

使用示例:

+ +
function MyConstructor (arguments) {
+    for (var nProp = 0; nProp < arguments.length; nProp++) {
+        this["property" + nProp] = arguments[nProp];
+    }
+}
+
+var myArray = [4, "Hello world!", false];
+var myInstance = new MyConstructor(myArray); //Fix MyConstructor.construct is not a function
+
+console.log(myInstance.property1);                // logs "Hello world!"
+console.log(myInstance instanceof MyConstructor); // logs "true"
+console.log(myInstance.constructor);              // logs "MyConstructor"
+
+ +
注意: 这个非native的Function.construct方法无法和一些native构造器(例如Date)一起使用。 在这种情况下你必须使用Function.bind方法(例如,想象有如下一个数组要用在Date构造器中: [2012, 11, 4];这时你需要这样写: new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))() – -无论如何这不是最好的实现方式并且也许不该用在任何生产环境中).
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.3.4.3', 'Function.prototype.apply')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-function.prototype.apply', 'Function.prototype.apply')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-function.prototype.apply', 'Function.prototype.apply')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Function.apply")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/arguments/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/arguments/index.html new file mode 100644 index 0000000000..a0c93f29f3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/arguments/index.html @@ -0,0 +1,125 @@ +--- +title: Function.arguments +slug: Web/JavaScript/Reference/Global_Objects/Function/arguments +translation_of: Web/JavaScript/Reference/Global_Objects/Function/arguments +--- +
{{JSRef}} {{deprecated_header}}
+ +

function.arguments 属性代表传入函数的实参,它是一个类数组对象。

+ +

描述

+ +

function.arguments 已经被废弃了, 现在推荐的做法是使用函数内部可用的 {{jsxref("Functions/arguments", "arguments")}} 对象来访问函数的实参。

+ +

在函数递归调用的时候(在某一刻同一个函数运行了多次,也就是有多套实参),那么 arguments 属性的值是最近一次该函数调用时传入的实参,下面的示例有演示。

+ +

如果函数不在执行期间,那么该函数的 arguments 属性的值是 null

+ +

示例

+ +
function f(n) { g(n - 1); }
+
+function g(n) {
+  console.log('before: ' + g.arguments[0]);
+  if (n > 0) { f(n); }
+  console.log('after: ' + g.arguments[0]);
+}
+
+f(2);
+
+console.log('函数退出后的 arguments 属性值:' + g.arguments);
+
+// 输出:
+
+// before: 1
+// before: 0
+// after: 0
+// after: 1
+// 函数退出后的 arguments 属性值:null
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES1')}}{{Spec2('ES1')}}arguments 属性首次实现于 JavaScript 1.0,首次添加进规范是在 ES1,在 ES3 中被删除。
{{SpecName('ES5.1', '#sec-10.6', 'arguments object')}}{{Spec2('ES5.1')}}{{jsxref("Functions/arguments", "arguments")}}
{{SpecName('ES6', '#sec-arguments-object', 'arguments object')}}{{Spec2('ES6')}}{{jsxref("Functions/arguments", "arguments")}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/arity/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/arity/index.html new file mode 100644 index 0000000000..d8e8668ca2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/arity/index.html @@ -0,0 +1,16 @@ +--- +title: Function.arity +slug: Web/JavaScript/Reference/Global_Objects/Function/arity +translation_of: Archive/Web/JavaScript/Function.arity +--- +
+
{{JSRef("Global_Objects", "Function")}} {{obsolete_header}}
+
+ +

概述

+ +

返回一个函数的形参数量.

+ +

描述

+ +

arity是一个古老的已经没有浏览器支持的属性,你应该使用Function.prototype.length属性来代替.

diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/bind/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/bind/index.html new file mode 100644 index 0000000000..fbabcdfc13 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/bind/index.html @@ -0,0 +1,324 @@ +--- +title: Function.prototype.bind() +slug: Web/JavaScript/Reference/Global_Objects/Function/bind +tags: + - ECMAScript 2015 + - ECMAScript 5 + - Function + - JavaScript + - Method + - polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/Function/bind +--- +
{{JSRef}}
+ +

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

+ +
{{EmbedInteractiveExample("pages/js/function-bind.html", "taller")}}
+ + + +

语法

+ +
function.bind(thisArg[, arg1[, arg2[, ...]]])
+ +

参数

+ +
+
thisArg
+
调用绑定函数时作为 this 参数传递给目标函数的值。 如果使用{{jsxref("Operators/new", "new")}}运算符构造绑定函数,则忽略该值。当使用 bindsetTimeout 中创建一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object。如果 bind 函数的参数列表为空,或者thisArgnullundefined,执行作用域的 this 将被视为新函数的 thisArg
+
arg1, arg2, ...
+
当目标函数被调用时,被预置入绑定函数的参数列表中的参数。
+
+ +

返回值

+ +

返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。

+ +

描述

+ +
bind() 函数会创建一个新的绑定函数bound function,BF)。绑定函数是一个 exotic function object(怪异函数对象,ECMAScript 2015 中的术语),它包装了原函数对象。调用绑定函数通常会导致执行包装函数
+绑定函数具有以下内部属性:
+ +
+ +
+ + +

当调用绑定函数时,它调用 [[BoundTargetFunction]] 上的内部方法 [[Call]],就像这样 Call(boundThis, args)。其中,boundThis[[BoundThis]]args[[BoundArguments]] 加上通过函数调用传入的参数列表。

+
+ +
+

绑定函数也可以使用 {{jsxref("Operators/new", "new")}} 运算符构造,它会表现为目标函数已经被构建完毕了似的。提供的 this 值会被忽略,但前置参数仍会提供给模拟函数。

+
+ +

示例

+ +

创建绑定函数

+ +

bind() 最简单的用法是创建一个函数,不论怎么调用,这个函数都有同样的 this 值。JavaScript新手经常犯的一个错误是将一个方法从对象中拿出来,然后再调用,期望方法中的 this 是原来的对象(比如在回调中传入这个方法)。如果不做特殊处理的话,一般会丢失原来的对象。基于这个函数,用原始的对象创建一个绑定函数,巧妙地解决了这个问题:

+ +
this.x = 9;    // 在浏览器中,this 指向全局的 "window" 对象
+var module = {
+  x: 81,
+  getX: function() { return this.x; }
+};
+
+module.getX(); // 81
+
+var retrieveX = module.getX;
+retrieveX();
+// 返回 9 - 因为函数是在全局作用域中调用的
+
+// 创建一个新函数,把 'this' 绑定到 module 对象
+// 新手可能会将全局变量 x 与 module 的属性 x 混淆
+var boundGetX = retrieveX.bind(module);
+boundGetX(); // 81
+
+ +

偏函数

+ +

bind() 的另一个最简单的用法是使一个函数拥有预设的初始参数。只要将这些参数(如果有的话)作为 bind() 的参数写在 this 后面。当绑定函数被调用时,这些参数会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们后面。

+ +
function list() {
+  return Array.prototype.slice.call(arguments);
+}
+
+function addArguments(arg1, arg2) {
+    return arg1 + arg2
+}
+
+var list1 = list(1, 2, 3); // [1, 2, 3]
+
+var result1 = addArguments(1, 2); // 3
+
+// 创建一个函数,它拥有预设参数列表。
+var leadingThirtysevenList = list.bind(null, 37);
+
+// 创建一个函数,它拥有预设的第一个参数
+var addThirtySeven = addArguments.bind(null, 37);
+
+var list2 = leadingThirtysevenList();
+// [37]
+
+var list3 = leadingThirtysevenList(1, 2, 3);
+// [37, 1, 2, 3]
+
+var result2 = addThirtySeven(5);
+// 37 + 5 = 42
+
+var result3 = addThirtySeven(5, 10);
+// 37 + 5 = 42 ,第二个参数被忽略
+
+ +

配合 setTimeout

+ +

在默认情况下,使用 {{ domxref("window.setTimeout()") }} 时,this 关键字会指向 {{ domxref("window") }} (或 global)对象。当类的方法中需要 this 指向类的实例时,你可能需要显式地把 this 绑定到回调函数,就不会丢失该实例的引用。

+ +
function LateBloomer() {
+  this.petalCount = Math.ceil(Math.random() * 12) + 1;
+}
+
+// 在 1 秒钟后声明 bloom
+LateBloomer.prototype.bloom = function() {
+  window.setTimeout(this.declare.bind(this), 1000);
+};
+
+LateBloomer.prototype.declare = function() {
+  console.log('I am a beautiful flower with ' +
+    this.petalCount + ' petals!');
+};
+
+var flower = new LateBloomer();
+flower.bloom();  // 一秒钟后, 调用 'declare' 方法
+ +

作为构造函数使用的绑定函数

+ +
+

警告 :这部分演示了 JavaScript 的能力并且记录了 bind() 的超前用法。以下展示的方法并不是最佳的解决方案,且可能不应该用在任何生产环境中。

+
+ +

绑定函数自动适应于使用 {{jsxref("Operators/new", "new")}} 操作符去构造一个由目标函数创建的新实例。当一个绑定函数是用来构建一个值的,原来提供的 this 就会被忽略。不过提供的参数列表仍然会插入到构造函数调用时的参数列表之前。

+ +
function Point(x, y) {
+  this.x = x;
+  this.y = y;
+}
+
+Point.prototype.toString = function() {
+  return this.x + ',' + this.y;
+};
+
+var p = new Point(1, 2);
+p.toString(); // '1,2'
+
+var emptyObj = {};
+var YAxisPoint = Point.bind(emptyObj, 0/*x*/);
+
+// 本页下方的 polyfill 不支持运行这行代码,
+// 但使用原生的 bind 方法运行是没问题的:
+
+var YAxisPoint = Point.bind(null, 0/*x*/);
+
+/*(译注:polyfill 的 bind 方法中,如果把 bind 的第一个参数加上,
+即对新绑定的 this 执行 Object(this),包装为对象,
+因为 Object(null) 是 {},所以也可以支持)*/
+
+var axisPoint = new YAxisPoint(5);
+axisPoint.toString(); // '0,5'
+
+axisPoint instanceof Point; // true
+axisPoint instanceof YAxisPoint; // true
+new YAxisPoint(17, 42) instanceof Point; // true
+ +

请注意,你不需要做特别的处理就可以用 {{jsxref("Operators/new", "new")}} 操作符创建一个绑定函数。也就是说,你不需要做特别处理就可以创建一个可以被直接调用的绑定函数,即使你更希望绑定函数是用 {{jsxref("Operators/new", "new")}} 操作符来调用。

+ +
// ...接着上面的代码继续的话,
+// 这个例子可以直接在你的 JavaScript 控制台运行
+
+// 仍然能作为一个普通函数来调用
+// (即使通常来说这个不是被期望发生的)
+YAxisPoint(13);
+
+emptyObj.x + ',' + emptyObj.y;   //  '0,13'
+
+ +

如果你希望一个绑定函数要么只能用 {{jsxref("Operators/new", "new")}} 操作符,要么只能直接调用,那你必须在目标函数上显式规定这个限制。

+ +

快捷调用

+ +

在你想要为一个需要特定的 this 值的函数创建一个捷径(shortcut)的时候,bind() 也很好用。

+ +

你可以用 {{jsxref("Array.prototype.slice")}} 来将一个类似于数组的对象(array-like object)转换成一个真正的数组,就拿它来举例子吧。你可以简单地这样写:

+ +
var slice = Array.prototype.slice;
+
+// ...
+
+slice.apply(arguments);
+ +

bind()可以使这个过程变得简单。在下面这段代码里面,slice 是 {{jsxref("Function.prototype")}} 的 {{jsxref("Function.prototype.apply()", "apply()")}} 方法的绑定函数,并且将 {{jsxref("Array.prototype")}} 的 {{jsxref("Array.prototype.slice()", "slice()")}} 方法作为 this 的值。这意味着我们压根儿用不着上面那个 apply()调用了。

+ +
// 与前一段代码的 "slice" 效果相同
+var unboundSlice = Array.prototype.slice;
+var slice = Function.prototype.apply.bind(unboundSlice);
+
+// ...
+
+slice(arguments);
+ +

Polyfill

+ +

有两种实现bind的方法,下面第一种不支持使用new调用新创建的构造函数,而第二种支持。

+ +
// Does not work with `new (funcA.bind(thisArg, args))`
+if (!Function.prototype.bind) (function(){
+  var slice = Array.prototype.slice;
+  Function.prototype.bind = function() {
+    var thatFunc = this, thatArg = arguments[0];
+    var args = slice.call(arguments, 1);
+    if (typeof thatFunc !== 'function') {
+      // closest thing possible to the ECMAScript 5
+      // internal IsCallable function
+      throw new TypeError('Function.prototype.bind - ' +
+             'what is trying to be bound is not callable');
+    }
+    return function(){
+      var funcArgs = args.concat(slice.call(arguments))
+      return thatFunc.apply(thatArg, funcArgs);
+    };
+  };
+})();
+ +

你可以将这段代码插入到你的脚本开头,从而使你的 bind() 在没有内置实现支持的环境中也可以部分地使用bind

+ +
//  Yes, it does work with `new (funcA.bind(thisArg, args))`
+if (!Function.prototype.bind) (function(){
+  var ArrayPrototypeSlice = Array.prototype.slice;
+  Function.prototype.bind = function(otherThis) {
+    if (typeof this !== 'function') {
+      // closest thing possible to the ECMAScript 5
+      // internal IsCallable function
+      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
+    }
+
+    var baseArgs= ArrayPrototypeSlice.call(arguments, 1),
+        baseArgsLength = baseArgs.length,
+        fToBind = this,
+        fNOP    = function() {},
+        fBound  = function() {
+          baseArgs.length = baseArgsLength; // reset to default base arguments
+          baseArgs.push.apply(baseArgs, arguments);
+          return fToBind.apply(
+                 fNOP.prototype.isPrototypeOf(this) ? this : otherThis, baseArgs
+          );
+        };
+
+    if (this.prototype) {
+      // Function.prototype doesn't have a prototype property
+      fNOP.prototype = this.prototype;
+    }
+    fBound.prototype = new fNOP();
+
+    return fBound;
+  };
+})();
+ +

上述算法和实际的实现算法还有许多其他的不同 (尽管可能还有其他不同之处,但已经没有必要再多列举):

+ + + +

如果你选择使用这部分实现,你不能依赖于那些与 ECMA-262, 5th edition 规定的行为偏离的例子。bind() 函数被广泛支持之前,某些情况下(或者为了兼容某些特定需求对其做一些特定修改后)可以选择用这个实现作为过渡。

+ +

请访问 https://github.com/Raynos/function-bind 以查找更完整的解决方案!

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES5.1', '#sec-15.3.4.5', 'Function.prototype.bind')}}{{Spec2('ES5.1')}}初始定义。在 JavaScript 1.8.5 中实现。
{{SpecName('ES2015', '#sec-function.prototype.bind', 'Function.prototype.bind')}}{{Spec2('ES2015')}}
{{SpecName('ESDraft', '#sec-function.prototype.bind', 'Function.prototype.bind')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Function.bind")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/call/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/call/index.html new file mode 100644 index 0000000000..5b9fc87b48 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/call/index.html @@ -0,0 +1,174 @@ +--- +title: Function.prototype.call() +slug: Web/JavaScript/Reference/Global_Objects/Function/call +tags: + - JavaScript + - 函数 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Function/call +--- +
{{JSRef}}
+ +

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

+ +
注意:该方法的语法和作用与 {{jsxref("Function.apply", "apply()")}} 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组
+ +
{{EmbedInteractiveExample("pages/js/function-call.html")}}
+ + + +

语法

+ +
function.call(thisArg, arg1, arg2, ...)
+ +

参数

+ +
+
thisArg
+
可选的。在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
+
arg1, arg2, ...
+
指定的参数列表。
+
+ +

返回值

+ +

使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined

+ +

描述

+ +

call() 允许为不同的对象分配和调用属于一个对象的函数/方法。

+ +

call() 提供新的 this 值给当前调用的函数/方法。你可以使用 call 来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。

+ +

示例

+ +

使用 call 方法调用父构造函数

+ +

在一个子构造函数中,你可以通过调用父构造函数的 call 方法来实现继承,类似于 Java 中的写法。下例中,使用 FoodToy 构造函数创建的对象实例都会拥有在 Product 构造函数中添加的 name 属性和 price 属性,但 category 属性是在各自的构造函数中定义的。

+ +
function Product(name, price) {
+  this.name = name;
+  this.price = price;
+}
+
+function Food(name, price) {
+  Product.call(this, name, price);
+  this.category = 'food';
+}
+
+function Toy(name, price) {
+  Product.call(this, name, price);
+  this.category = 'toy';
+}
+
+var cheese = new Food('feta', 5);
+var fun = new Toy('robot', 40);
+
+ +

使用 call 方法调用匿名函数

+ +

在下例中的 for 循环体内,我们创建了一个匿名函数,然后通过调用该函数的 call 方法,将每个数组元素作为指定的 this 值执行了那个匿名函数。这个匿名函数的主要目的是给每个数组元素对象添加一个 print 方法,这个 print 方法可以打印出各元素在数组中的正确索引号。当然,这里不是必须得让数组元素作为 this 值传入那个匿名函数(普通参数就可以),目的是为了演示 call 的用法。

+ +
var animals = [
+  { species: 'Lion', name: 'King' },
+  { species: 'Whale', name: 'Fail' }
+];
+
+for (var i = 0; i < animals.length; i++) {
+  (function(i) {
+    this.print = function() {
+      console.log('#' + i + ' ' + this.species
+                  + ': ' + this.name);
+    }
+    this.print();
+  }).call(animals[i], i);
+}
+
+ +

使用 call 方法调用函数并且指定上下文的 'this'

+ +

在下面的例子中,当调用 greet 方法的时候,该方法的this值会绑定到 obj 对象。

+ +
function greet() {
+  var reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
+  console.log(reply);
+}
+
+var obj = {
+  animal: 'cats', sleepDuration: '12 and 16 hours'
+};
+
+greet.call(obj);  // cats typically sleep between 12 and 16 hours
+
+ +

使用 call 方法调用函数并且不指定第一个参数(argument

+ +

在下面的例子中,我们调用了 display 方法,但并没有传递它的第一个参数。如果没有传递第一个参数,this 的值将会被绑定为全局对象。

+ +
var sData = 'Wisen';
+
+function display() {
+  console.log('sData value is %s ', this.sData);
+}
+
+display.call();  // sData value is Wisen
+ +
+

注意:在严格模式下,this 的值将会是 undefined。见下文。

+
+ +
'use strict';
+
+var sData = 'Wisen';
+
+function display() {
+  console.log('sData value is %s ', this.sData);
+}
+
+display.call(); // Cannot read the property of 'sData' of undefined
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本状态说明
{{SpecName('ES1')}}{{Spec2('ES1')}}初始定义。在 JavaScript 1.3 中实现。
{{SpecName('ES5.1', '#sec-15.3.4.4', 'Function.prototype.call')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-function.prototype.call', 'Function.prototype.call')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-function.prototype.call', 'Function.prototype.call')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Function.call")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/caller/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/caller/index.html new file mode 100644 index 0000000000..a850d41582 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/caller/index.html @@ -0,0 +1,69 @@ +--- +title: Function.caller +slug: Web/JavaScript/Reference/Global_Objects/Function/caller +translation_of: Web/JavaScript/Reference/Global_Objects/Function/caller +--- +
{{JSRef("Global_Objects", "Function")}} {{non-standard_header}}
+ +

概述

+ +

返回调用指定函数的函数.

+ +

该属性不是ECMA-262第3版标准的一部分.不过, SpiderMonkey (Mozilla的JavaScript引擎) (查看{{ Bug("65683") }}), V8 (Chrome的JavaScript引擎) 和 JScript(IE的ECMAScript实现)都已经支持了它.

+ +

描述

+ +

如果一个函数f是在全局作用域内被调用的,则f.caller为null,相反,如果一个函数是在另外一个函数作用域内被调用的,则f.caller指向调用它的那个函数.

+ +

该属性的常用形式arguments.callee.caller替代了被废弃的 arguments.caller.

+ +

备注

+ +

注意,在使用递归调用时, 你不能使用此属性来重现出调用栈.请考虑以下代码:

+ +
function f(n) { g(n-1) }
+function g(n) { if(n>0) f(n); else stop() }
+f(2)
+
+ +

stop()函数被调用时,调用栈是这样的:

+ +
f(2) -> g(1) -> f(1) -> g(0) -> stop()
+
+ +

由于下面的表达式为 true(只保留函数最后一次被调用时的caller):

+ +
stop.caller === g && f.caller === g && g.caller === f
+
+ +

所以如果你尝试在stop()函数中获取调用栈的话:

+ +
var f = stop;
+var stack = "调用栈:";
+while (f) {
+  stack += "\n" + f.name;
+  f = f.caller;
+}
+
+ +

则上面的代码会进入一个死循环.

+ +

有一个特殊属性 __caller__, 可以返回调用当前函数的函数的活动对象(可以用来重现出整个调用栈), 但由于安全原因的考虑,该属性已被删除.

+ +

例子

+ +

例子: 检测一个函数的caller属性的值

+ +

下例用来得出一个函数是被谁调用的.

+ +
function myFunc() {
+   if (myFunc.caller == null) {
+      return ("该函数在全局作用域内被调用!");
+   } else
+      return ("调用我的是函数是" + myFunc.caller);
+}
+
+ +

浏览器兼容性

+ +

Function.caller目前被所有主流浏览器支持: Firefox, Safari, Chrome, Opera 和 IE. 查看检测结果.

diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/displayname/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/displayname/index.html new file mode 100644 index 0000000000..abf8452f93 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/displayname/index.html @@ -0,0 +1,121 @@ +--- +title: Function.displayName +slug: Web/JavaScript/Reference/Global_Objects/Function/displayName +translation_of: Web/JavaScript/Reference/Global_Objects/Function/displayName +--- +
{{JSRef}} {{non-standard_header}}
+ +

function.displayName 属性获取函数的显示名称

+ +

Description 描述

+ +

当一个函数的 displayName 属性被定义,这个函数的 displayName 属性将返回显示名称。

+ +
function doSomething() {}
+
+console.log(doSomething.displayName); // "undefined"
+
+var popup = function(content) { console.log(content); };
+
+popup.displayName = 'Show Popup';
+
+console.log(popup.displayName); // "Show Popup"
+
+ +

可以在函数表达式重定义函数的显示名称{{jsxref("Functions", "function expression", "", 1)}}:

+ +
var object = {
+  someMethod: function() {}
+};
+
+object.someMethod.displayName = 'someMethod';
+
+console.log(object.someMethod.displayName); // logs "someMethod"
+
+try { someMethod } catch(e) { console.log(e); }
+// ReferenceError: someMethod is not defined
+
+ +

可以动态修改函数的显示名称:

+ +
var object = {
+  // anonymous
+  someMethod: function(value) {
+    arguments.callee.displayName = 'someMethod (' + value + ')';
+  }
+};
+
+console.log(object.someMethod.displayName); // "undefined"
+
+object.someMethod('123')
+console.log(object.someMethod.displayName); // "someMethod (123)"
+
+ +

Examples 例子

+ +

这个显示名称通常在控制台和配置文件中,用它来提醒对它背后的真实函数名 {{jsxref("Function.name", "func.name")}}的引用。例如:

+ +

通过如下的举例,显示的名称应该显示像"function My Function()"

+ +
var a = function() {};
+a.displayName = 'My Function';
+
+a; // "function My Function()"
+ +

Specifications 规范

+ +

不属于任何规范

+ +

Browser compatibility 浏览器兼容性

+ +

如果你愿意贡献数据,请访问https://github.com/mdn/browser-compat-data并同时给我们发送推送请求。

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop(13)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/index.html new file mode 100644 index 0000000000..217ac78e3d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/index.html @@ -0,0 +1,156 @@ +--- +title: Function +slug: Web/JavaScript/Reference/Global_Objects/Function +tags: + - Constructor + - Function + - JavaScript + - 函数 + - 构造器 +translation_of: Web/JavaScript/Reference/Global_Objects/Function +--- +
{{JSRef}}
+ +
每个 JavaScript 函数实际上都是一个 Function 对象。运行 (function(){}).constructor === Function // true 便可以得到这个结论。
+ +

构造函数

+ +

Function 构造函数创建一个新的 Function 对象。直接调用此构造函数可用动态创建函数,但会遇到和 {{jsxref("eval")}} 类似的的安全问题和(相对较小的)性能问题。然而,与 eval 不同的是,Function 创建的函数只能在全局作用域中运行。

+ +
{{EmbedInteractiveExample("pages/js/function-constructor.html")}}
+ + + +

语法

+ +
new Function ([arg1[, arg2[, ...argN]],] functionBody)
+ +

参数

+ +
+
arg1, arg2, ... argN
+
被函数使用的参数的名称必须是合法命名的。参数名称是一个有效的JavaScript标识符的字符串,或者一个用逗号分隔的有效字符串的列表;例如“×”,“theValue”,或“a,b”。
+
functionBody
+
一个含有包括函数定义的 JavaScript 语句的字符串
+
+ +

描述

+ +

使用 Function 构造器生成的 Function 对象是在函数创建时解析的。这比你使用函数声明或者函数表达式并在你的代码中调用更为低效,因为使用后者创建的函数是跟其他代码一起解析的。

+ +

所有被传递到构造函数中的参数,都将被视为将被创建的函数的参数,并且是相同的标示符名称和传递顺序。

+ +

以调用函数的方式调用 Function 的构造函数(而不是使用 new 关键字) 跟以构造函数来调用是一样的。

+ +

属性和方法

+ +

全局的 Function 对象没有自己的属性和方法,但是,因为它本身也是一个函数,所以它也会通过原型链从自己的原型链 {{jsxref("Function.prototype")}} 上继承一些属性和方法。

+ +

原型对象

+ +

属性

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype', '属性')}}
+ +

方法

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype', '方法')}}
+ +

实例

+ +

Function 实例从 {{jsxref("Function.prototype")}} 继承了一些属性和方法。 同其他构造函数一样, 你可以改变构造函数的原型从而使得所有的 Function 实例的属性和方法发生改变。

+ +

示例

+ +

传入参数调用 Function 构造函数

+ +

下面的代码会创建一个需要两个参数的 Function 对象。

+ +
// 可以直接在 JavaScript 控制台中运行
+
+// 创建了一个能返回两个参数和的函数
+const adder = new Function("a", "b", "return a + b");
+
+// 调用函数
+adder(2, 6);
+// > 8
+
+ +

参数 "a" 和 "b" 是参数的名字,在函数体中被使用,"return a + b"。

+ +

Function 构造器与函数声明之间的不同

+ +

由 Function 构造器创建的函数不会创建当前环境的闭包,它们总是被创建于全局环境,因此在运行时它们只能访问全局变量和自己的局部变量,不能访问它们被 Function 构造器创建时所在的作用域的变量。这一点与使用 {{jsxref("eval")}} 执行创建函数的代码不同。

+ +
var x = 10;
+
+function createFunction1() {
+    var x = 20;
+    return new Function('return x;'); // 这里的 x 指向最上面全局作用域内的 x
+}
+
+function createFunction2() {
+    var x = 20;
+    function f() {
+        return x; // 这里的 x 指向上方本地作用域内的 x
+    }
+    return f;
+}
+
+var f1 = createFunction1();
+console.log(f1());          // 10
+var f2 = createFunction2();
+console.log(f2());          // 20
+
+ +

虽然这段代码可以在浏览器中正常运行,但在 Node.js 中 f1() 会产生一个“找不到变量 x ”的 ReferenceError。这是因为在 Node 中顶级作用域不是全局作用域,而 x 其实是在当前模块的作用域之中。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.3', 'Function')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-function-objects', 'Function')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-function-objects', 'Function')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Function")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/isgenerator/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/isgenerator/index.html new file mode 100644 index 0000000000..f377f0a210 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/isgenerator/index.html @@ -0,0 +1,40 @@ +--- +title: Function.prototype.isGenerator() +slug: Web/JavaScript/Reference/Global_Objects/Function/isGenerator +translation_of: Archive/Web/JavaScript/Function.isGenerator +--- +
{{JSRef("Global_Objects", "Function")}} {{non-standard_header}}
+ +

概述

+ +

判断一个函数是否是一个生成器.

+ +

语法

+ +
fun.isGenerator()
+ +

描述

+ +

该方法用来判断一个函数是否是一个生成器.

+ +

例子

+ +
function f() {}
+function* g() {
+  yield 42;
+}
+console.log("f.isGenerator() = " + f.isGenerator());
+console.log("g.isGenerator() = " + g.isGenerator());
+
+ +

上面代码的输出结果为

+ +
f.isGenerator() = false
+g.isGenerator() = true
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/length/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/length/index.html new file mode 100644 index 0000000000..9804d07a75 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/length/index.html @@ -0,0 +1,89 @@ +--- +title: Function.length +slug: Web/JavaScript/Reference/Global_Objects/Function/length +tags: + - Function + - JavaScript + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Function/length +--- +
{{JSRef}}
+ +

length 属性指明函数的形参个数。

+ +

{{EmbedInteractiveExample("pages/js/function-length.html")}}

+ +
{{js_property_attributes(0,0,1)}}
+ +

描述

+ +

length 是函数对象的一个属性值,指该函数有多少个必须要传入的参数,即形参的个数。

+ +

形参的数量不包括剩余参数个数,仅包括第一个具有默认值之前的参数个数。

+ +

与之对比的是,  {{jsxref("Functions_and_function_scope/arguments/length", "arguments.length")}} 是函数被调用时实际传参的个数。

+ +

Function 构造器的属性

+ +

{{jsxref("Function")}} 构造器本身也是个Function。他的 length 属性值为 1 。该属性 Writable: false, Enumerable: false, Configurable: true.

+ +

Function.prototype 对象的属性

+ +

 {{jsxref("Function.prototype")}}  对象的 length 属性值为 0 。

+ +

示例

+ +
console.log(Function.length); /* 1 */
+
+console.log((function()        {}).length); /* 0 */
+console.log((function(a)       {}).length); /* 1 */
+console.log((function(a, b)    {}).length); /* 2 etc. */
+
+console.log((function(...args) {}).length);
+// 0, rest parameter is not counted
+
+console.log((function(a, b = 1, c) {}).length);
+// 1, only parameters before the first one with
+// a default value is counted
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.3.5.1', 'Function.length')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function-instances-length', 'Function.length')}}{{Spec2('ES6')}}The configurable attribute of this property is now true.
{{SpecName('ESDraft', '#sec-function-instances-length', 'Function.length')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +
{{Compat("javascript.builtins.Function.length")}}
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/name/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/name/index.html new file mode 100644 index 0000000000..3c701acdca --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/name/index.html @@ -0,0 +1,219 @@ +--- +title: Function.name +slug: Web/JavaScript/Reference/Global_Objects/Function/name +tags: + - ECMAScript 2015 + - Function + - JavaScript + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Function/name +--- +
{{JSRef("Global_Objects", "Function")}}
+ +
function.name 属性返回函数实例的名称。
+ +

{{js_property_attributes(0,0,1)}}

+ +
+

请注意,在非标准的ES2015之前的实现中,configurable属性也是false 。

+
+ +

示例

+ +

函数声明的名称

+ +

 name 属性返回一个函数声明的名称。

+ +
function doSomething() { }
+doSomething.name;  // "doSomething"
+
+ +

构造函数的名称

+ +

使用new Function(...)语法创建的函数或只是 Function(...) create {{jsxref("Function")}}对象及其名称为“anonymous”。

+ +
(new Function).name; // "anonymous"
+ +

推断函数名称

+ +

变量和方法可以从句法位置推断匿名函数的名称(ECMAScript 2015中新增)。

+ +
var f = function() {};
+var object = {
+  someMethod: function() {}
+};
+
+console.log(f.name); // "f"
+console.log(object.someMethod.name); // "someMethod"
+ +

你可以在 {{jsxref("Operators/Function", "函数表达式", "", 1)}}中定义函数的名称:

+ +
var object = {
+  someMethod: function object_someMethod() {}
+};
+
+console.log(object.someMethod.name); // "object_someMethod"
+
+try { object_someMethod } catch(e) { alert(e); }
+// ReferenceError: object_someMethod is not defined
+
+ +

你不能更改函数的名称,此属性是只读的:

+ + + +
var object = {
+  // anonymous
+  someMethod: function() {}
+};
+
+object.someMethod.name = 'otherMethod';
+console.log(object.someMethod.name); // someMethod
+ +

要更改它,可以使用{{jsxref("Object.defineProperty()")}}。

+ +

简写方法的名称

+ +
var o = {
+  foo(){}
+};
+o.foo.name; // "foo";
+ +

绑定函数的名称

+ +

{{jsxref("Function.bind()")}} 所创建的函数将会在函数的名称前加上"bound " 。

+ +
function foo() {};
+foo.bind({}).name; // "bound foo"
+ +

getters 和 setters 的函数名

+ +

当通过 get 和 set 访问器来存取属性时, "get" 或 "set" 会出现在函数名称前。

+ +
var o = {
+  get foo(){},
+  set foo(x){}
+};
+
+var descriptor = Object.getOwnPropertyDescriptor(o, "foo");
+descriptor.get.name; // "get foo"
+descriptor.set.name; // "set foo";
+ +

类中的函数名称

+ +

你可以使用obj.constructor.name来检查对象的“类”(但请务必阅读以下警告):

+ +
function Foo() {}  // ES2015 Syntax: class Foo {}
+
+var fooInstance = new Foo();
+console.log(fooInstance.constructor.name); // logs "Foo"
+ +
+

警告:脚本解释器只有在函数没有名为name的属性时才会设置内置的Function.name属性(参见 9.2.11 of the ECMAScript2015 Language Specification)。但是,ES2015规定由关键字static修饰的静态方法也会被认为是类的属性(ECMAScript2015, 14.5.14.21.b + 12.2.6.9)。

+
+ +

因此,我们无法获取具有静态方法属性name()的几乎任何类的类名称:

+ +
class Foo {
+  constructor() {}
+  static name() {}
+}
+
+ +

使用static name()方法Foo.name不再保存实际的类名称,而是引用name()函数对象。 ES2015语法中的上述类定义将在Chrome或Firefox中运行,类似于ES5语法中的以下代码段:

+ +
function Foo() {}
+Object.defineProperty(Foo, 'name', { writable: true });
+Foo.name = function() {};
+
+ +

通过fooInstance.constructor.name获取fooInstance类不会给我们所有的类名,而是静态类方法的引用。 例如:

+ +
var fooInstance = new Foo();
+console.log(fooInstance.constructor.name); // logs function name()
+ +

你也可以从ES5语法示例中看到,在Chrome或Firefox的中静态定义的Foo.name变得可写。内置定义在没有自定义静态定义时是只读的:

+ +
Foo.name = 'Hello';
+console.log(Foo.name);
+//如果Foo具有静态name()属性,则输出“Hello”,否则为“Foo”
+
+ +

因此,你不能依赖内置的Function.name属性来保持一个类的名称。

+ +

Symbol作为函数名称

+ +

如果{{jsxref("Symbol")}} 被用于函数名称,并且这个symbol具有相应的描述符,那么方法的名字就是方括号中的描述符。

+ +
var sym1 = Symbol("foo");
+var sym2 = Symbol();
+var o = {
+  [sym1]: function(){},
+  [sym2]: function(){}
+};
+
+o[sym1].name; // "[foo]"
+o[sym2].name; // ""
+
+ +

JavaScript 压缩和 minifiers

+ +
+

警告:当使用Function.name和那些JavaScript压缩器(minifiers)或混淆器进行源码转换时要小心。这些工具通常用作JavaScript构建管道的一部分,以在程序部署到生产之前减少程序的大小。但这种转换通常会在构建时更改函数的名称。

+
+ +

例如下面的代码:

+ +
function Foo() {};
+var foo = new Foo();
+
+if (foo.constructor.name === 'Foo') {
+  console.log("'foo' is an instance of 'Foo'");
+} else {
+  console.log('Oops!');
+}
+ +

可能被压缩为:

+ +
function a() {};
+var b = new a();
+if (b.constructor.name === 'Foo') {
+  console.log("'foo' is an instance of 'Foo'");
+} else {
+  console.log('Oops!');
+}
+
+ +

在未压缩版本中,程序运行到真实分支并打印'foo' is an instance of 'Foo'。 而在压缩版本中,它的行为不同,并且进入else分支。如果您依赖于Function.name,就像上面的示例一样,确保您的构建管道不会更改函数名称,也不要假定函数具有特定的名称。

+ +
+

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-name', 'name')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-name', 'name')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Function.name")}}

+
diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/prototype/index.html new file mode 100644 index 0000000000..afae311604 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/prototype/index.html @@ -0,0 +1,138 @@ +--- +title: Function.prototype +slug: Web/JavaScript/Reference/Global_Objects/Function/prototype +tags: + - JavaScript + - 函数 + - 原型 + - 原型属性 +translation_of: Web/JavaScript/Reference/Global_Objects/Function +--- +
{{JSRef}}
+ +

Function.prototype 属性存储了 {{jsxref("Function")}} 的原型对象。

+ +

描述

+ +

{{jsxref("Function")}}对象继承自 Function.prototype 属性。因此,Function.prototype 不能被修改。

+ +

属性

+ +
+
{{jsxref("Function.arguments")}} {{deprecated_inline()}}
+
以数组形式获取传入函数的所有参数。此属性已被{{jsxref("Functions_and_function_scope/arguments", "arguments")}}替代。
+
{{jsxref("Function.arity")}} {{obsolete_inline() }}
+
用于指定的函数的参数的个数,但已被删除。使用{{jsxref("Function.length","length")}}属性代替。
+
{{jsxref("Function.caller")}} {{ Non-standard_inline() }}
+
获取调用函数的具体对象。
+
{{jsxref("Function.length")}}
+
获取函数的接收参数个数。
+
{{jsxref("Function.name")}} {{ Non-standard_inline() }}
+
获取函数的名称。
+
{{jsxref("Function.displayName")}} {{ Non-standard_inline() }}
+
获取函数的display name。
+
Function.prototype.constructor
+
声明函数的原型构造方法,详细请参考 {{jsxref("Object.constructor")}} 。
+
+ +

方法

+ +
+
{{jsxref("Function.prototype.apply()")}}
+
在一个对象的上下文中应用另一个对象的方法;参数能够以数组形式传入。
+
{{jsxref("Function.prototype.bind()")}}
+
bind()方法会创建一个新函数,称为绑定函数.当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数.
+
{{jsxref("Function.prototype.call()")}}
+
在一个对象的上下文中应用另一个对象的方法;参数能够以列表形式传入。
+
{{jsxref("Function.prototype.isGenerator()")}} {{ Non-standard_inline() }}
+
若函数对象为generator,返回true,反之返回 false
+
{{jsxref("Function.prototype.toSource()")}} {{ Non-standard_inline() }}
+
获取函数的实现源码的字符串。 覆盖了 {{jsxref("Object.prototype.toSource")}} 方法。
+
{{jsxref("Function.prototype.toString()")}}
+
获取函数的实现源码的字符串。覆盖了 {{jsxref("Object.prototype.toString")}} 方法。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-15.3.5.2', 'Function.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function-instances-prototype', 'Function.prototype')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/tosource/index.html new file mode 100644 index 0000000000..5c4de38138 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/tosource/index.html @@ -0,0 +1,49 @@ +--- +title: Function.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/Function/toSource +translation_of: Web/JavaScript/Reference/Global_Objects/Function/toSource +--- +
+
{{JSRef("Global_Objects", "Function")}} {{non-standard_header}}
+
+ +

概述

+ +

返回函数的源代码的字符串表示.

+ +

语法

+ +
function.toSource();
+Function.toSource();
+
+ +

参数

+ +

+ +

描述

+ +

toSource方法返回下面的值:

+ +

+ + + +
function Function() {
+    [native code]
+}
+ + + +

该方法通常在引擎内部调用.你可以在调试的时候用该方法开查看一个函数的源代码.

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/tostring/index.html new file mode 100644 index 0000000000..01bf4d2ce7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/function/tostring/index.html @@ -0,0 +1,230 @@ +--- +title: Function.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/Function/toString +tags: + - Function + - JavaScript + - Method +translation_of: Web/JavaScript/Reference/Global_Objects/Function/toString +--- +
{{JSRef}}
+ +

toString() 方法返回一个表示当前函数源代码的字符串。

+ +
{{EmbedInteractiveExample("pages/js/function-tostring.html")}}
+ +

语法

+ +
function.toString()
+ +

返回值

+ +

表示函数源代码的一个字符串

+ +

描述

+ +

{{jsxref("Function")}}对象覆盖了从{{jsxref("Object")}}继承来的{{jsxref("Object.prototype.toString", "toString")}} 方法。对于用户定义的 {{jsxref("Function")}} 对象,toString方法返回一个字符串,其中包含用于定义函数的源文本段。

+ +

在{{jsxref("Function")}}需要转换为字符串时,通常会自动调用函数的 toString 方法。

+ +

this 不是 Function 对象,则 toString() 方法将抛出 {{jsxref("TypeError")}}  ("Function.prototype.toString called on incompatible object") 异常,比如 {{jsxref("Proxy")}} 对象就会抛出异常。

+ +
Function.prototype.toString.call('foo'); // TypeError
+
+ +

如果是在内置函数或由 Function.prototype.bind 返回的函数上调用 toString(),则toString() 返回原生代码字符串,如下

+ +
"function () {\n    [native code]\n}"
+
+ +

若是在由 Function 构造器生成的函数上调用 toString() ,则 toString() 返回创建后的函数源码,包括形参和函数体,函数名为 "anonymous"。

+ +

示例

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionFunction.prototype.toString result
+
+function f(){}
+
+
+"function f(){}"
+
+
+class A { a(){} }
+
+
+"class A { a(){} }"
+
+
+function* g(){}
+
+
+"function* g(){}"
+
+
+a => a
+
+
+"a => a"
+
+
+({ a(){} }.a)
+
+
+"a(){}"
+
+
+({ *a(){} }.a)
+
+
+"*a(){}"
+
+
+({ [0](){} }[0])
+
+
+"[0](){}"
+
+
+Object.getOwnPropertyDescriptor({
+    get a(){}
+}, "a").get
+
+
+"get a(){}"
+
+
+Object.getOwnPropertyDescriptor({
+    set a(x){}
+}, "a").set
+
+
+"set a(x){}"
+
+
+Function.prototype.toString
+
+
+"function toString() { [native code] }"
+
+
+(function f(){}.bind(0))
+
+
+"function () { [native code] }"
+
+
+Function("a", "b")
+
+
+"function anonymous(a\n) {\nb\n}"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}初始定义。在 JavaScript 1.1 中实现。
{{SpecName('ES6', '#sec-function.prototype.tostring', 'Function.prototype.toString')}}{{Spec2('ES6')}}对字符串表示增加了更多的特定需求。
Function.prototype.toString revisionDraft对内置函数与行尾表示进行标准化。
{{SpecName('ESDraft', '#sec-function.prototype.tostring', 'Function.prototype.toString')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Function.toString")}}

+
+ +

附注(针对Firefox)

+ + + +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/generator/index.html b/files/zh-cn/web/javascript/reference/global_objects/generator/index.html new file mode 100644 index 0000000000..612024ca88 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/generator/index.html @@ -0,0 +1,142 @@ +--- +title: Generator +slug: Web/JavaScript/Reference/Global_Objects/Generator +tags: + - ECMAScript 2015 + - Generator + - JavaScript + - Legacy Generator + - Legacy Iterator + - 参考 + - 生成器 +translation_of: Web/JavaScript/Reference/Global_Objects/Generator +--- +
{{JSRef}} 
+ +

生成器对象是由一个 {{jsxref("Statements/function*", "generator function", "", 1)}} 返回的,并且它符合可迭代协议迭代器协议

+ +

语法

+ +
function* gen() {
+  yield 1;
+  yield 2;
+  yield 3;
+}
+
+let g = gen();
+// "Generator { }"
+ +

方法

+ +
+
{{jsxref("Generator.prototype.next()")}}
+
返回一个由 {{jsxref("Operators/yield", "yield")}}表达式生成的值。
+
{{jsxref("Generator.prototype.return()")}}
+
返回给定的值并结束生成器。
+
{{jsxref("Generator.prototype.throw()")}}
+
向生成器抛出一个错误。
+
+ +

示例

+ +

一个无限迭代器

+ +
function* idMaker(){
+    let index = 0;
+    while(true)
+        yield index++;
+}
+
+let gen = idMaker(); // "Generator { }"
+
+console.log(gen.next().value);
+// 0
+console.log(gen.next().value);
+// 1
+console.log(gen.next().value);
+// 2
+// ...
+ +

传统的生成器对象

+ +

Firefox (SpiderMonkey) 在 JavaScript 1.7 中也实现了一个较早版本的生成器,其中函数声明中的星号(*)不是必需的 (只需在函数体中使用yield 关键字)。但是,旧式生成器已弃用。不要使用它们;他们将被删除  ({{bug(1083482)}})。

+ +

传统的生成器方法

+ +
+
Generator.prototype.next() {{non-standard_inline}}
+
返回 {{jsxref("Operators/yield", "yield")}} 表达式产生的值. 与ES2015 生成器对象的next()方法对应.
+
Generator.prototype.close() {{non-standard_inline}}
+
关闭生成器,因此执行该函数后调用next()函数时将会抛出 {{jsxref("StopIteration")}} 错误. 与ES2015 生成器对象的return()方法对应..
+
Generator.prototype.send() {{non-standard_inline}}
+
用于将值发送到生成器。 该值由 {{jsxref("Operators/yield", "yield")}} 表达式返回, 并且返回下一个 {{jsxref("Operators/yield", "yield")}} 表达式产生的值. send(x) 对应于ES2015生成器对象中的 next(x)
+
Generator.prototype.throw() {{non-standard_inline}}
+
向生成器抛出错误. 与ES2015 生成器对象的throw()方法对应.
+
+ +

旧生成器对象示例

+ +
function fibonacci() {
+  var a = yield 1;
+  yield a * 2;
+}
+
+var it = fibonacci();
+console.log(it);          // "Generator {  }"
+console.log(it.next());   // 1
+console.log(it.send(10)); // 20
+console.log(it.close());  // undefined
+console.log(it.next());   // throws StopIteration (as the generator is now closed)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-generator-objects', 'Generator objects')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-generator-objects', 'Generator objects')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Generator")}}

+ +

相关链接

+ +

Legacy generators

+ + + +

ES2015 generators

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/generator/next/index.html b/files/zh-cn/web/javascript/reference/global_objects/generator/next/index.html new file mode 100644 index 0000000000..96ad60c35c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/generator/next/index.html @@ -0,0 +1,165 @@ +--- +title: Generator.prototype.next() +slug: Web/JavaScript/Reference/Global_Objects/Generator/next +tags: + - ECMAScript 2015 + - Generator + - JavaScript + - 原型 + - 参考 + - 方法 + - 生成器 +translation_of: Web/JavaScript/Reference/Global_Objects/Generator/next +--- +
{{JSRef}}
+ +

next() 方法返回一个包含属性 donevalue 的对象。该方法也可以通过接受一个参数用以向生成器传值。

+ +

语法

+ +
gen.next(value)
+ +

参数

+ +
+
value
+
向生成器传递的值.
+
+ +

返回值

+ +

返回的对象包含两个属性:

+ + + +

示例

+ +

使用 next()方法

+ +

下面的例子展示了一个简单的生成器, 以及调用 next 后方法的返回值:

+ +
function* gen() {
+  yield 1;
+  yield 2;
+  yield 3;
+}
+
+var g = gen(); // "Generator { }"
+g.next();      // "Object { value: 1, done: false }"
+g.next();      // "Object { value: 2, done: false }"
+g.next();      // "Object { value: 3, done: false }"
+g.next();      // "Object { value: undefined, done: true }"
+
+ +

向生成器传值

+ +

在此示例中,使用值调用next。 请注意,第一次调用没有记录任何内容,因为生成器最初没有产生任何结果。

+ +
function* gen() {
+  while(true) {
+    var value = yield null;
+    console.log(value);
+  }
+}
+
+var g = gen();
+g.next(1);
+// "{ value: null, done: false }"
+g.next(2);
+// 2
+// "{ value: null, done: false }"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-generator.prototype.next', 'Generator.prototype.next')}}{{Spec2('ES6')}}初始定义
{{SpecName('ESDraft', '#sec-generator.prototype.next', 'Generator.prototype.next')}}{{Spec2('ESDraft')}}草案
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}13{{CompatGeckoDesktop(26)}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatSafari(10)}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support5.1{{CompatVersionUnknown}}{{CompatGeckoMobile(26)}}{{CompatUnknown}}{{CompatUnknown}}10
+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/generator/return/index.html b/files/zh-cn/web/javascript/reference/global_objects/generator/return/index.html new file mode 100644 index 0000000000..9c5ed4bb99 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/generator/return/index.html @@ -0,0 +1,99 @@ +--- +title: Generator.prototype.return() +slug: Web/JavaScript/Reference/Global_Objects/Generator/return +tags: + - ECMAScript6 + - JavaScript + - 原型 + - 参考 + - 方法 + - 生成器 +translation_of: Web/JavaScript/Reference/Global_Objects/Generator/return +--- +
{{JSRef}}
+ +

return() 方法返回给定的值并结束生成器。

+ +

语法

+ +
gen.return(value)
+ +

参数

+ +
+
value
+
需要返回的值
+
+ +

返回值

+ +

返回该函数参数中给定的值.

+ +

示例

+ +

使用 return()

+ +

以下例子展示了一个简单的生成器和 return 方法的使用.

+ +
function* gen() {
+  yield 1;
+  yield 2;
+  yield 3;
+}
+
+var g = gen();
+
+g.next();        // { value: 1, done: false }
+g.return("foo"); // { value: "foo", done: true }
+g.next();        // { value: undefined, done: true }
+
+ +

如果对已经处于“完成”状态的生成器调用return(value),则生成器将保持在“完成”状态。如果没有提供参数,则返回对象的value属性与示例最后的.next()方法相同。如果提供了参数,则参数将被设置为返回对象的value属性的值。

+ +
function* gen() {
+  yield 1;
+  yield 2;
+  yield 3;
+}
+
+var g = gen();
+g.next(); // { value: 1, done: false }
+g.next(); // { value: 2, done: false }
+g.next(); // { value: 3, done: false }
+g.next(); // { value: undefined, done: true }
+g.return(); // { value: undefined, done: true }
+g.return(1); // { value: 1, done: true }
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-generator.prototype.return', 'Generator.prototype.return')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-generator.prototype.return', 'Generator.prototype.return')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Generator.return")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/generator/throw/index.html b/files/zh-cn/web/javascript/reference/global_objects/generator/throw/index.html new file mode 100644 index 0000000000..13138d5484 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/generator/throw/index.html @@ -0,0 +1,142 @@ +--- +title: Generator.prototype.throw() +slug: Web/JavaScript/Reference/Global_Objects/Generator/throw +tags: + - ECMAScript6 + - JavaScript + - 参考 + - 属性 + - 方法 + - 生成器 +translation_of: Web/JavaScript/Reference/Global_Objects/Generator/throw +--- +
{{JSRef}}
+ +

throw() 方法用来向生成器抛出异常,并恢复生成器的执行,返回带有 donevalue 两个属性的对象。

+ +

语法

+ +
gen.throw(exception)
+ +

参数

+ +
+
exception
+
用于抛出的异常。 使用 {{jsxref("Error")}} 的实例对调试非常有帮助.
+
+ +

返回值

+ +

带有两个属性的{{jsxref("Object", "对象")}}:

+ + + +

示例

+ +

使用 throw()

+ +

下面的例子展示了一个简单的生成器并使用 throw方法向该生成器抛出一个异常,该异常通常可以通过 try...catch 块进行捕获.

+ +
function* gen() {
+  while(true) {
+    try {
+       yield 42;
+    } catch(e) {
+      console.log("Error caught!");
+    }
+  }
+}
+
+var g = gen();
+g.next(); // { value: 42, done: false }
+g.throw(new Error("Something went wrong")); // "Error caught!"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-generator.prototype.throw', 'Generator.prototype.throw')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-generator.prototype.throw', 'Generator.prototype.throw')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop(26)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile(26)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/generatorfunction/index.html b/files/zh-cn/web/javascript/reference/global_objects/generatorfunction/index.html new file mode 100644 index 0000000000..ab93243b97 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/generatorfunction/index.html @@ -0,0 +1,113 @@ +--- +title: GeneratorFunction +slug: Web/JavaScript/Reference/Global_Objects/GeneratorFunction +tags: + - Constructor + - ECMAScript 2015 + - GeneratorFunction + - Iterator + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/GeneratorFunction +--- +
{{JSRef("Global_Objects", "生成器函数")}}
+ +

GeneratorFunction构造器生成新的{{jsxref("Statements/function*", "生成器函数")}} 对象。在JavaScript中,生成器函数实际上都是GeneratorFunction的实例对象。

+ +

注意,GeneratorFunction并不是一个全局对象。它可以通过下面的代码获取。

+ +
Object.getPrototypeOf(function*(){}).constructor
+
+ +

语法

+ +
new GeneratorFunction ([arg1[, arg2[, ...argN]],] functionBody)
+ +

参数

+ +
+
arg1, arg2, ... argN
+
函数使用的名称作为形式参数名称。每个必须是一个字符串,对应于一个有效的JavaScript标识符或这样的字符串的列表,用逗号分隔;如“x”,“theValue”或“a,b”。
+
functionBody
+
一个包含多条表示JavaScript函数体语句的字符串。
+
+ +

描述

+ +

当创建函数时,将使用GeneratorFunction构造函数创建的{{jsxref("Statements/function*", "生成器函数")}}对象进行解析。这比使用{{jsxref("Statements/function*", "function* 表达式")}} 声明生成器函数效率更低,并且在代码中调用它,因为这些函数与其余的代码一起被解析。

+ +

传递给函数的所有参数按照它们被传递的顺序被视为要创建的函数中参数的标识符的名称。

+ +
+

提示:使用GeneratorFunction构造函数创建的{{jsxref("Statements/function*", "生成器函数")}}不会为其创建上下文创建闭包;它们始终在全局范围内创建。当运行它们时,它们只能访问自己的本地变量和全局变量,而不是从GeneratorFunction构造函数调用的范围的变量。这与使用{{jsxref("Global_Objects/eval", "eval")}}与生成函数表达式的代码不同。

+
+ +

GeneratorFunction构造函数调用为函数(不使用new运算符)与将其作为构造函数调用的效果相同。

+ +

属性

+ +
+
GeneratorFunction.length
+
GeneratorFunction构造函数的 length 属性值为 1。
+
{{jsxref("GeneratorFunction.prototype")}}
+
允许向所有生成器函数对象添加属性。
+
+ +

GeneratorFunction 原型对象

+ +

属性

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype', 'Properties')}}
+ +

GeneratorFunction 实例

+ +

GeneratorFunction实例从{{jsxref("GeneratorFunction.prototype")}}继承方法和属性。与所有构造函数一样,你可以更改构造函数的原型对象以对所有GeneratorFunction实例进行更改。

+ +

示例

+ +

GeneratorFunction构造函数创建一个生成器函数

+ +
var GeneratorFunction = Object.getPrototypeOf(function*(){}).constructor
+var g = new GeneratorFunction("a", "yield a * 2");
+var iterator = g(10);
+console.log(iterator.next().value); // 20
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-generatorfunction-objects', 'GeneratorFunction')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-generatorfunction-objects', 'GeneratorFunction')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.GeneratorFunction")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/generatorfunction/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/generatorfunction/prototype/index.html new file mode 100644 index 0000000000..c723725c05 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/generatorfunction/prototype/index.html @@ -0,0 +1,64 @@ +--- +title: GeneratorFunction.prototype +slug: Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype +tags: + - ECMAScript 2015 + - GeneratorFunction + - Iterator + - JavaScript + - Property + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/GeneratorFunction +--- +
{{JSRef}}
+ +

GeneratorFunction.prototype属性是{{jsxref("GeneratorFunction")}}的原型对象。

+ +

描述

+ +

{{jsxref("GeneratorFunction")}} 的实例对象都继承于 GeneratorFunction.prototype. GeneratorFunction.prototype 不能被修改。

+ +

属性

+ +
+
GeneratorFunction.constructor
+
初始值是 {{jsxref("GeneratorFunction")}}.
+
GeneratorFunction.prototype.prototype
+
值是 %GeneratorPrototype%.
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-generatorfunction.prototype', 'GeneratorFunction.prototype')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-generatorfunction.prototype', 'GeneratorFunction.prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.GeneratorFunction.prototype")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/globalthis/index.html b/files/zh-cn/web/javascript/reference/global_objects/globalthis/index.html new file mode 100644 index 0000000000..8e0e0feeb2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/globalthis/index.html @@ -0,0 +1,92 @@ +--- +title: globalThis +slug: Web/JavaScript/Reference/Global_Objects/globalThis +tags: + - JavaScript + - Reference + - global + - globalThis + - this + - 全局 + - 参考 + - 属性 +translation_of: Web/JavaScript/Reference/Global_Objects/globalThis +--- +
{{jsSidebar("Objects")}}
+ +

全局属性 globalThis 包含全局的 this 值,类似于全局对象(global object)。

+ +
{{EmbedInteractiveExample("pages/js/globalprops-globalthis.html","shorter")}}
+ + + +

{{JS_Property_Attributes(1, 0, 1)}}

+ +

语法

+ +
globalThis
+ +

描述

+ +

在以前,从不同的 JavaScript 环境中获取全局对象需要不同的语句。在 Web 中,可以通过 windowself 或者 frames 取到全局对象,但是在 Web Workers 中,只有 self 可以。在 Node.js 中,它们都无法获取,必须使用 global

+ +

在松散模式下,可以在函数中返回 this 来获取全局对象,但是在严格模式和模块环境下,this 会返回 undefined。 You can also use Function('return this')(), but environments that disable {{jsxref("eval", "eval()")}}, like CSP in browsers, prevent use of {{jsxref("Function")}} in this way.

+ +

globalThis 提供了一个标准的方式来获取不同环境下的全局 this  对象(也就是全局对象自身)。不像 window 或者 self 这些属性,它确保可以在有无窗口的各种环境下正常工作。所以,你可以安心的使用 globalThis,不必担心它的运行环境。为便于记忆,你只需要记住,全局作用域中的 this 就是 globalThis

+ +

HTML 与 WindowProxy

+ +

在很多引擎中, globalThis 被认为是真实的全局对象的引用,但是在浏览器中,由于 iframe 以及跨窗口安全性的考虑,它实际引用的是真实全局对象(不可以被直接访问)的 {{jsxref("Proxy")}} 代理。在通常的应用中,很少会涉及到代理与对象本身的区别,但是也需要加以注意。

+ +

命名

+ +

并没有采用一些更常见的命名方式类似 self 和 global 是因为考虑到前向兼容,为了避免影响到现存代码的正常工作。 更多相关信息可以查看 language proposal's "naming" document 。

+ +

示例

+ +

globalThis 之前,获取某个全局对象的唯一方式就是 Function('return this')(),但是这在某些情况下会违反 CSP 规则,所以,es6-shim 使用了类似如下的方式:

+ +
var getGlobal = function () {
+  if (typeof self !== 'undefined') { return self; }
+  if (typeof window !== 'undefined') { return window; }
+  if (typeof global !== 'undefined') { return global; }
+  throw new Error('unable to locate global object');
+};
+
+var globals = getGlobal();
+
+if (typeof globals.setTimeout !== 'function') {
+  // 此环境中没有 setTimeout 方法!
+}
+
+ +

但是有了 globalThis 之后,只需要:

+ +
if (typeof globalThis.setTimeout !== 'function') {
+  //  此环境中没有 setTimeout 方法!
+}
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName("ESDraft", "#sec-globalthis", "globalThis")}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.globalThis")}}

+ +

实现进度

+ +

下表提供了此特性的每日实施状态,因为该功能尚未达到跨浏览器的稳定性。 通过在每个浏览器的JavaScript引擎的daily版本或最新版本中运行 Test262(JavaScript 的标准测试套件)中的相关功能测试得到了如下数据。

+ +
{{EmbedTest262ReportResultsTable("globalThis")}}
diff --git a/files/zh-cn/web/javascript/reference/global_objects/index.html b/files/zh-cn/web/javascript/reference/global_objects/index.html new file mode 100644 index 0000000000..293b4935b6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/index.html @@ -0,0 +1,208 @@ +--- +title: JavaScript 标准内置对象 +slug: Web/JavaScript/Reference/Global_Objects +tags: + - JavaScript + - Reference + - 参考 + - 总览 +translation_of: Web/JavaScript/Reference/Global_Objects +--- +
{{JSSidebar("Objects")}}
+ +

本章介绍和说明了 JavaScript 中所有的标准内置对象、以及它们的方法和属性。

+ +

这里的术语"全局对象"(或标准内置对象)不应与global对象混淆。这里的"全局对象"指的是处在全局作用域里的多个对象

+ +

global对象可以在全局作用域里通过使用{{JSxRef("Operators/this", "this")}}访问到(但只有在 ECMAScript 5 的非严格模式下才可以,在严格模式下得到的是 {{JSxRef("undefined")}})。其实全局作用域包含全局对象中的属性,包括它可能继承来的属性。

+ +

全局作用域中的其他对象则可由用户的脚本创建,或由宿主程序提供。浏览器环境中所提供的宿主对象的说明可以在这里找到:API 参考

+ +

要了解关于 DOM 和核心 JavaScript 之间区别的更多信息,可参阅 JavaScript 技术概述

+ +

标准内置对象分类

+ +

值属性

+ +

这些全局属性返回一个简单值,这些值没有自己的属性和方法。

+ + + +

函数属性

+ +

全局函数可以直接调用,不需要在调用时指定所属对象,执行结束后会将结果直接返回给调用者。

+ +
+ +
+ +

基本对象

+ +

顾名思义,基本对象是定义或使用其他对象的基础。基本对象包括一般对象、函数对象和错误对象。

+ + + +

错误对象

+ +

错误对象是一种特殊的基本对象。它们拥有基本的 {{JSxRef("Error")}} 类型,同时也有多种具体的错误类型。

+ +
+ +
+ +

数字和日期对象

+ +

用来表示数字、日期和执行数学计算的对象。

+ + + +

字符串

+ +

用来表示和操作字符串的对象。

+ + + +

可索引的集合对象

+ +

这些对象表示按照索引值来排序的数据集合,包括数组和类型数组,以及类数组结构的对象。

+ +
+ +
+ +

使用键的集合对象

+ +

这些集合对象在存储数据时会使用到键,包括可迭代的{{JSxRef("Map")}} 和 {{JSxRef("Set")}},支持按照插入顺序来迭代元素。

+ + + +

结构化数据

+ +

这些对象用来表示和操作结构化的缓冲区数据,或使用 JSON (JavaScript Object Notation)编码的数据。

+ + + +

控制抽象对象

+ +

控件抽象可以帮助构造代码,尤其是异步代码(例如,不使用深度嵌套的回调)。

+ + + +

反射

+ + + +

国际化

+ +

ECMAScript核心的附加功能,用于支持多语言处理

+ +
+ +
+ +

WebAssembly

+ +
+ +
+ +

其他

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/infinity/index.html b/files/zh-cn/web/javascript/reference/global_objects/infinity/index.html new file mode 100644 index 0000000000..7d8e6cb3c4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/infinity/index.html @@ -0,0 +1,57 @@ +--- +title: Infinity +slug: Web/JavaScript/Reference/Global_Objects/Infinity +tags: + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/Infinity +--- +
{{jsSidebar("Objects")}}
+ +

全局属性 Infinity 是一个数值,表示无穷大。

+ +

{{js_property_attributes(0,0,0)}}

+ +

{{EmbedInteractiveExample("pages/js/globalprops-infinity.html")}}

+ +

描述

+ +

Infinity全局对象global object)的一个属性,即它是一个全局变量。

+ +

Infinity 的初始值是 {{jsxref("Number.POSITIVE_INFINITY")}}。Infinity(正无穷大)大于任何值。

+ +

该值的意义与数学无穷大略有不同。 有关详细信息,请参见{{jsxref("Number.POSITIVE_INFINITY")}}。

+ +

在 ECMAScript 5 的规范中, Infinity 是只读的(实现于 JavaScript 1.8.5 / Firefox 4)。

+ +

示例

+ +
console.log(Infinity          ); /* Infinity */
+console.log(Infinity + 1      ); /* Infinity */
+console.log(Math.pow(10, 1000)); /* Infinity */
+console.log(Math.log(0)       ); /* -Infinity */
+console.log(1 / Infinity      ); /* 0 */
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-value-properties-of-the-global-object-infinity', 'Infinity')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Infinity")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/int16array/index.html b/files/zh-cn/web/javascript/reference/global_objects/int16array/index.html new file mode 100644 index 0000000000..0626eed988 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/int16array/index.html @@ -0,0 +1,254 @@ +--- +title: Int16Array +slug: Web/JavaScript/Reference/Global_Objects/Int16Array +translation_of: Web/JavaScript/Reference/Global_Objects/Int16Array +--- +
{{JSRef}}
+ +

The Int16Array typed array represents an array of twos-complement 16-bit signed integers in the platform byte order. If control over byte order is needed, use {{jsxref("DataView")}} instead. The contents are initialized to 0. Once established, you can reference elements in the array using the object's methods, or using standard array index syntax (that is, using bracket notation).

+ +

语法

+ +
new Int16Array(length);
+new Int16Array(typedArray);
+new Int16Array(object);
+new Int16Array(buffer [, byteOffset [, length]]);
+ +

For more information about the constructor syntax and the parameters, see TypedArray.

+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "Int16Array.BYTES_PER_ELEMENT")}}
+
Returns a number value of the element size. 2 in the case of an Int16Array.
+
Int16Array.length
+
Static length property whose value is 3. For the actual length (number of elements), see {{jsxref("TypedArray.prototype.length", "Int16Array.prototype.length")}}.
+
{{jsxref("TypedArray.name", "Int16Array.name")}}
+
Returns the string value of the constructor name. In the case of the Int16Array type: "Int16Array".
+
{{jsxref("TypedArray.prototype", "Int16Array.prototype")}}
+
Prototype for the TypedArray objects.
+
+ +

方法

+ +
+
{{jsxref("TypedArray.from", "Int16Array.from()")}}
+
Creates a new Int16Array from an array-like or iterable object. See also {{jsxref("Array.from()")}}.
+
{{jsxref("TypedArray.of", "Int16Array.of()")}}
+
Creates a new Int16Array with a variable number of arguments. See also {{jsxref("Array.of()")}}.
+
+ +

Int16Array prototype

+ +

All Int16Array objects inherit from {{jsxref("TypedArray.prototype", "%TypedArray%.prototype")}}.

+ +

Properties

+ +
+
Int16Array.prototype.constructor
+
Returns the function that created an instance's prototype. This is the Int16Array constructor by default.
+
{{jsxref("TypedArray.prototype.buffer", "Int16Array.prototype.buffer")}} {{readonlyInline}}
+
Returns the {{jsxref("ArrayBuffer")}} referenced by the Int16Array Fixed at construction time and thus read only.
+
{{jsxref("TypedArray.prototype.byteLength", "Int16Array.prototype.byteLength")}} {{readonlyInline}}
+
Returns the length (in bytes) of the Int16Array from the start of its {{jsxref("ArrayBuffer")}}. Fixed at construction time and thus read only.
+
{{jsxref("TypedArray.prototype.byteOffset", "Int16Array.prototype.byteOffset")}} {{readonlyInline}}
+
Returns the offset (in bytes) of the Int16Array from the start of its {{jsxref("ArrayBuffer")}}. Fixed at construction time and thus read only.
+
{{jsxref("TypedArray.prototype.length", "Int16Array.prototype.length")}} {{readonlyInline}}
+
Returns the number of elements hold in the Int16Array. Fixed at construction time and thus read only.
+
+ +

Methods

+ +
+
{{jsxref("TypedArray.copyWithin", "Int16Array.prototype.copyWithin()")}}
+
Copies a sequence of array elements within the array. See also {{jsxref("Array.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.entries", "Int16Array.prototype.entries()")}}
+
Returns a new Array Iterator object that contains the key/value pairs for each index in the array. See also {{jsxref("Array.prototype.entries()")}}.
+
{{jsxref("TypedArray.every", "Int16Array.prototype.every()")}}
+
Tests whether all elements in the array pass the test provided by a function. See also {{jsxref("Array.prototype.every()")}}.
+
{{jsxref("TypedArray.fill", "Int16Array.prototype.fill()")}}
+
Fills all the elements of an array from a start index to an end index with a static value. See also {{jsxref("Array.prototype.fill()")}}.
+
{{jsxref("TypedArray.filter", "Int16Array.prototype.filter()")}}
+
Creates a new array with all of the elements of this array for which the provided filtering function returns true. See also {{jsxref("Array.prototype.filter()")}}.
+
{{jsxref("TypedArray.find", "Int16Array.prototype.find()")}}
+
Returns the found value in the array, if an element in the array satisfies the provided testing function or undefined if not found. See also {{jsxref("Array.prototype.find()")}}.
+
{{jsxref("TypedArray.findIndex", "Int16Array.prototype.findIndex()")}}
+
Returns the found index in the array, if an element in the array satisfies the provided testing function or -1 if not found. See also {{jsxref("Array.prototype.findIndex()")}}.
+
{{jsxref("TypedArray.forEach", "Int16Array.prototype.forEach()")}}
+
Calls a function for each element in the array. See also {{jsxref("Array.prototype.forEach()")}}.
+
{{jsxref("TypedArray.includes", "Int16Array.prototype.includes()")}} {{experimental_inline}}
+
Determines whether a typed array includes a certain element, returning true or false as appropriate. See also {{jsxref("Array.prototype.includes()")}}.
+
{{jsxref("TypedArray.indexOf", "Int16Array.prototype.indexOf()")}}
+
Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.indexOf()")}}.
+
{{jsxref("TypedArray.join", "Int16Array.prototype.join()")}}
+
Joins all elements of an array into a string. See also {{jsxref("Array.prototype.join()")}}.
+
{{jsxref("TypedArray.keys", "Int16Array.prototype.keys()")}}
+
Returns a new Array Iterator that contains the keys for each index in the array. See also {{jsxref("Array.prototype.keys()")}}.
+
{{jsxref("TypedArray.lastIndexOf", "Int16Array.prototype.lastIndexOf()")}}
+
Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.lastIndexOf()")}}.
+
{{jsxref("TypedArray.map", "Int16Array.prototype.map()")}}
+
Creates a new array with the results of calling a provided function on every element in this array. See also {{jsxref("Array.prototype.map()")}}.
+
{{jsxref("TypedArray.move", "Int16Array.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
+
Former non-standard version of {{jsxref("TypedArray.copyWithin", "Int16Array.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.reduce", "Int16Array.prototype.reduce()")}}
+
Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. See also {{jsxref("Array.prototype.reduce()")}}.
+
{{jsxref("TypedArray.reduceRight", "Int16Array.prototype.reduceRight()")}}
+
Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. See also {{jsxref("Array.prototype.reduceRight()")}}.
+
{{jsxref("TypedArray.reverse", "Int16Array.prototype.reverse()")}}
+
Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first. See also {{jsxref("Array.prototype.reverse()")}}.
+
{{jsxref("TypedArray.set", "Int16Array.prototype.set()")}}
+
Stores multiple values in the typed array, reading input values from a specified array.
+
{{jsxref("TypedArray.slice", "Int16Array.prototype.slice()")}}
+
Extracts a section of an array and returns a new array. See also {{jsxref("Array.prototype.slice()")}}.
+
{{jsxref("TypedArray.some", "Int16Array.prototype.some()")}}
+
Returns true if at least one element in this array satisfies the provided testing function. See also {{jsxref("Array.prototype.some()")}}.
+
{{jsxref("TypedArray.sort", "Int16Array.prototype.sort()")}}
+
Sorts the elements of an array in place and returns the array. See also {{jsxref("Array.prototype.sort()")}}.
+
{{jsxref("TypedArray.subarray", "Int16Array.prototype.subarray()")}}
+
Returns a new Int16Array from the given start and end element index.
+
{{jsxref("TypedArray.values", "Int16Array.prototype.values()")}}
+
Returns a new Array Iterator object that contains the values for each index in the array. See also {{jsxref("Array.prototype.values()")}}.
+
{{jsxref("TypedArray.toLocaleString", "Int16Array.prototype.toLocaleString()")}}
+
Returns a localized string representing the array and its elements. See also {{jsxref("Array.prototype.toLocaleString()")}}.
+
{{jsxref("TypedArray.toString", "Int16Array.prototype.toString()")}}
+
Returns a string representing the array and its elements. See also {{jsxref("Array.prototype.toString()")}}.
+
{{jsxref("TypedArray.@@iterator", "Int16Array.prototype[@@iterator]()")}}
+
Returns a new Array Iterator object that contains the values for each index in the array.
+
+ +

Examples

+ +
// From a length
+var int16 = new Int16Array(2);
+int16[0] = 42;
+console.log(int16[0]); // 42
+console.log(int16.length); // 2
+console.log(int16.BYTES_PER_ELEMENT); // 2
+
+// From an array
+var arr = new Int16Array([21,31]);
+console.log(arr[1]); // 31
+
+// From another TypedArray
+var x = new Int16Array([21, 31]);
+var y = new Int16Array(x);
+console.log(y[0]); // 21
+
+// From an ArrayBuffer
+var buffer = new ArrayBuffer(8);
+var z = new Int16Array(buffer, 0, 4);
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 2015.
{{SpecName('ES2015', '#table-49', 'TypedArray constructors')}}{{Spec2('ES2015')}}Initial definition in an ECMA standard. Specified that new is required.
{{SpecName('ESDraft', '#table-49', 'TypedArray constructors')}}{{Spec2('ESDraft')}} 
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support7.0{{ CompatGeckoDesktop(2) }}1011.65.1
new is required{{CompatUnknown}}{{ CompatGeckoDesktop(44) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile(2) }}1011.64.2
new is required{{CompatUnknown}}{{CompatUnknown}}{{ CompatGeckoMobile(44) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

Compatibility notes

+ +

Starting with ECMAScript 2015, Int16Array constructors require to be constructed with a {{jsxref("Operators/new", "new")}} operator. Calling a Int16Array constructor as a function without new, will throw a {{jsxref("TypeError")}} from now on.

+ +
var dv = Int16Array([1, 2, 3]);
+// TypeError: calling a builtin Int16Array constructor
+// without new is forbidden
+ +
var dv = new Int16Array([1, 2, 3]);
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/int32array/index.html b/files/zh-cn/web/javascript/reference/global_objects/int32array/index.html new file mode 100644 index 0000000000..1e7ca21cc4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/int32array/index.html @@ -0,0 +1,259 @@ +--- +title: Int32Array +slug: Web/JavaScript/Reference/Global_Objects/Int32Array +translation_of: Web/JavaScript/Reference/Global_Objects/Int32Array +--- +
{{JSRef}}
+ +

该 Int32Array 类型表示在平台顺序字节中一个双补码32位有符号的整型数组。如果需要控制字节顺序,请改用{{jsxref("DataView")}} 。此内容的初始化为0。一旦创建,你可以使用对象的方法或者标准数组索引的语法(即使用括号表示法)。

+ +

语法

+ +
new Int32Array(length);
+new Int32Array(typedArray);
+new Int32Array(object);
+new Int32Array(buffer [, byteOffset [, length]]);
+ +

更多关于构造函数语法和参数的详细信息,请参阅TypedArray

+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "Int32Array.BYTES_PER_ELEMENT")}}
+
Returns a number value of the element size. 4 in the case of an Int32Array.   
+
Int32Array.length
+
Static length property whose value is 3. For the actual length (number of elements), see {{jsxref("TypedArray.prototype.length", "Int32Array.prototype.length")}}.
+
{{jsxref("TypedArray.name", "Int32Array.name")}}
+
Returns the string value of the constructor name. In the case of the Int32Array type: "Int32Array".
+
{{jsxref("TypedArray.prototype", "Int32Array.prototype")}}
+
Prototype for the TypedArray objects.
+
+ +

方法

+ +
+
{{jsxref("TypedArray.from", "Int32Array.from()")}}
+
从类似数组或者可迭代对象中创建一个新的Int32Array。另见{{jsxref("Array.from()")}}.
+
{{jsxref("TypedArray.of", "Int32Array.of()")}}
+
创建一个新的具有可变数量参数的Int32Array。另见{{jsxref("Array.of()")}}。
+
+ +

Int32Array 属性

+ +

所有的Int32Array对象都继承自{jsxref("TypedArray.prototype", "%TypedArray%.prototype")}}。

+ +

属性

+ +
+
Int32Array.prototype.constructor
+
返回创建实例原型的函数。默认情况下,它是Int32Array的构造函数。
+
{{jsxref("TypedArray.prototype.buffer", "Int32Array.prototype.buffer")}} {{readonlyInline}}
+
返回在构造时被固定的Int32Array引用的{{jsxref("ArrayBuffer")}},因此只读。
+
{{jsxref("TypedArray.prototype.byteLength", "Int32Array.prototype.byteLength")}} {{readonlyInline}}
+
返回从其{{jsxref("ArrayBuffer")}}开始的Int32Array长度的(以字节为单位)。在构造时被固定,因此只读。
+
{{jsxref("TypedArray.prototype.byteOffset", "Int32Array.prototype.byteOffset")}} {{readonlyInline}}
+
返回从其{{jsxref("ArrayBuffer")}}开始的偏移量(以字节为单位)。在构造时被固定,因此只读。
+
+ +
+
{{jsxref("TypedArray.prototype.length", "Int32Array.prototype.length")}} {{readonlyInline}}
+
     返回Int32ArrayInt32Array包含的元素个数。在构造时被固定,因此只读。
+
+ +

方法

+ +
+
{{jsxref("TypedArray.copyWithin", "Int32Array.prototype.copyWithin()")}}
+
Copies a sequence of array elements within the array. See also {{jsxref("Array.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.entries", "Int32Array.prototype.entries()")}}
+
Returns a new Array Iterator object that contains the key/value pairs for each index in the array. See also {{jsxref("Array.prototype.entries()")}}.
+
{{jsxref("TypedArray.every", "Int32Array.prototype.every()")}}
+
Tests whether all elements in the array pass the test provided by a function. See also {{jsxref("Array.prototype.every()")}}.
+
{{jsxref("TypedArray.fill", "Int32Array.prototype.fill()")}}
+
Fills all the elements of an array from a start index to an end index with a static value. See also {{jsxref("Array.prototype.fill()")}}.
+
{{jsxref("TypedArray.filter", "Int32Array.prototype.filter()")}}
+
Creates a new array with all of the elements of this array for which the provided filtering function returns true. See also {{jsxref("Array.prototype.filter()")}}.
+
{{jsxref("TypedArray.find", "Int32Array.prototype.find()")}}
+
Returns the found value in the array, if an element in the array satisfies the provided testing function or undefined if not found. See also {{jsxref("Array.prototype.find()")}}.
+
{{jsxref("TypedArray.findIndex", "Int32Array.prototype.findIndex()")}}
+
Returns the found index in the array, if an element in the array satisfies the provided testing function or -1 if not found. See also {{jsxref("Array.prototype.findIndex()")}}.
+
{{jsxref("TypedArray.forEach", "Int32Array.prototype.forEach()")}}
+
Calls a function for each element in the array. See also {{jsxref("Array.prototype.forEach()")}}.
+
{{jsxref("TypedArray.includes", "Int32Array.prototype.includes()")}} {{experimental_inline}}
+
Determines whether a typed array includes a certain element, returning true or false as appropriate. See also {{jsxref("Array.prototype.includes()")}}.
+
{{jsxref("TypedArray.indexOf", "Int32Array.prototype.indexOf()")}}
+
Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.indexOf()")}}.
+
{{jsxref("TypedArray.join", "Int32Array.prototype.join()")}}
+
Joins all elements of an array into a string. See also {{jsxref("Array.prototype.join()")}}.
+
{{jsxref("TypedArray.keys", "Int32Array.prototype.keys()")}}
+
Returns a new Array Iterator that contains the keys for each index in the array. See also {{jsxref("Array.prototype.keys()")}}.
+
{{jsxref("TypedArray.lastIndexOf", "Int32Array.prototype.lastIndexOf()")}}
+
Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.lastIndexOf()")}}.
+
{{jsxref("TypedArray.map", "Int32Array.prototype.map()")}}
+
Creates a new array with the results of calling a provided function on every element in this array. See also {{jsxref("Array.prototype.map()")}}.
+
{{jsxref("TypedArray.move", "Int32Array.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
+
Former non-standard version of {{jsxref("TypedArray.copyWithin", "Int32Array.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.reduce", "Int32Array.prototype.reduce()")}}
+
Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. See also {{jsxref("Array.prototype.reduce()")}}.
+
{{jsxref("TypedArray.reduceRight", "Int32Array.prototype.reduceRight()")}}
+
Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. See also {{jsxref("Array.prototype.reduceRight()")}}.
+
{{jsxref("TypedArray.reverse", "Int32Array.prototype.reverse()")}}
+
Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first. See also {{jsxref("Array.prototype.reverse()")}}.
+
{{jsxref("TypedArray.set", "Int32Array.prototype.set()")}}
+
在类型化数组中存储多个值,从指定数组中读取输入值。
+
{{jsxref("TypedArray.slice", "Int32Array.prototype.slice()")}}
+
提取数组中的一部分,并返回一个新的数组.更多请见{{jsxref("Array.prototype.slice()")}}。
+
{{jsxref("TypedArray.some", "Int32Array.prototype.some()")}}
+
如果数组中至少有一个元素满足所提供的测试函数,则返回true。更多请见{{jsxref("Array.prototype.some()")}}。
+
{{jsxref("TypedArray.sort", "Int32Array.prototype.sort()")}}
+
Sorts the elements of an array in place and returns the array. See also {{jsxref("Array.prototype.sort()")}}.
+
{{jsxref("TypedArray.subarray", "Int32Array.prototype.subarray()")}}
+
Returns a new Int32Array from the given start and end element index.
+
{{jsxref("TypedArray.values", "Int32Array.prototype.values()")}}
+
Returns a new Array Iterator object that contains the values for each index in the array. See also {{jsxref("Array.prototype.values()")}}.
+
{{jsxref("TypedArray.toLocaleString", "Int32Array.prototype.toLocaleString()")}}
+
Returns a localized string representing the array and its elements. See also {{jsxref("Array.prototype.toLocaleString()")}}.
+
{{jsxref("TypedArray.toString", "Int32Array.prototype.toString()")}}
+
Returns a string representing the array and its elements. See also {{jsxref("Array.prototype.toString()")}}.
+
{{jsxref("TypedArray.@@iterator", "Int32Array.prototype[@@iterator]()")}}
+
Returns a new Array Iterator object that contains the values for each index in the array.
+
+ +

例子

+ +

不同的方式创建一个 Int32Array

+ +
// 从一个数字
+var int32 = new Int32Array(2);
+int32[0] = 42;
+console.log(int32[0]); // 42
+console.log(int32.length); // 2
+console.log(int32.BYTES_PER_ELEMENT); // 4
+
+// 从一个数组
+var arr = new Int32Array([21,31]);
+console.log(arr[1]); // 31
+
+// 从一个其他TypedArray
+var x = new Int32Array([21, 31]);
+var y = new Int32Array(x);
+console.log(y[0]); // 21
+
+// 从一个ArrayBuffer
+var buffer = new ArrayBuffer(16);
+var z = new Int32Array(buffer, 0, 4);
+
+ +

详细描述

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}已被ECMAScript 6取代.
{{SpecName('ES6', '#table-49', 'TypedArray constructors')}}{{Spec2('ES6')}}ECMA标准中的初始定义,指定需要新建。
{{SpecName('ESDraft', '#table-49', 'TypedArray constructors')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持7.0{{ CompatGeckoDesktop(2) }}1011.65.1
的特性{{CompatUnknown}}{{ CompatGeckoDesktop(44) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile(2) }}1011.64.2
的特性{{CompatUnknown}}{{CompatUnknown}}{{ CompatGeckoMobile(44) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

兼容性说明

+ +

Starting with ECMAScript 2015 (ES6), In32Array constructors require to be constructed with a {{jsxref("Operators/new", "new")}} operator. Calling a Int32Array constructor as a function without new, will throw a {{jsxref("TypeError")}} from now on.

+ +
var dv = Int32Array([1, 2, 3]);
+// TypeError: calling a builtin Int32Array constructor
+// without new is forbidden
+ +
var dv = new Int32Array([1, 2, 3]);
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/int8array/index.html b/files/zh-cn/web/javascript/reference/global_objects/int8array/index.html new file mode 100644 index 0000000000..a2916916a9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/int8array/index.html @@ -0,0 +1,258 @@ +--- +title: Int8Array +slug: Web/JavaScript/Reference/Global_Objects/Int8Array +tags: + - Int8Array + - 构造器 + - 特定类型数组 +translation_of: Web/JavaScript/Reference/Global_Objects/Int8Array +--- +
{{JSRef}}
+ +

Int8Array 类型数组表示二进制补码8位有符号整数的数组。内容初始化为0。 一旦建立,你可以使用对象的方法引用数组中的元素,或使用标准数组索引语法( 即,使用括号注释)。

+ +

语法

+ +
new Int8Array(length);
+new Int8Array(typedArray);
+new Int8Array(object);
+new Int8Array(buffer [, byteOffset [, length]]);
+ +

有关构造函数语法和参数的更多信息,请访问 TypedArray.

+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "Int8Array.BYTES_PER_ELEMENT")}}
+
返回数组中每个元素的大小. 在Int8Array中这个值为1.
+
Int8Array.length
+
此属性为固定值属性,值为3.查看 {{jsxref("TypedArray.prototype.length", "Int8Array.prototype.length")}}获得获取数组内元素个数方法。
+
{{jsxref("TypedArray.name", "Int8Array.name")}}
+
返回构造器方法名称.在Int8Array类型中此值为 "Int8Array"。
+
{{jsxref("TypedArray.prototype", "Int8Array.prototype")}}
+
TypedArray 对象的构造原型。
+
+ +

方法

+ +
+
{{jsxref("TypedArray.from", "Int8Array.from()")}}
+
从类数组对象或迭代器生成int8Array数组对象. 参照{{jsxref("Array.from()")}}.
+
{{jsxref("TypedArray.of", "Int8Array.of()")}}
+
以多个参数构造Int8Array对象, 参照 {{jsxref("Array.of()")}}.
+
+ +

Int8Array 原型方法

+ +

所有 Int8Array对象都继承自 {{jsxref("TypedArray.prototype", "%TypedArray%.prototype")}}.

+ +

属性

+ +
+
Int8Array.prototype.constructor
+
这个方法会返回对象的构造原型. 默认为Int8Array构造函数.
+
{{jsxref("TypedArray.prototype.buffer", "Int8Array.prototype.buffer")}} {{readonlyInline}}
+
Returns the {{jsxref("ArrayBuffer")}} referenced by the Int8Array Fixed at construction time and thus read only.
+
{{jsxref("TypedArray.prototype.byteLength", "Int8Array.prototype.byteLength")}} {{readonlyInline}}
+
Returns the length (in bytes) of the Int8Array from the start of its {{jsxref("ArrayBuffer")}}. Fixed at construction time and thus read only.
+
{{jsxref("TypedArray.prototype.byteOffset", "Int8Array.prototype.byteOffset")}} {{readonlyInline}}
+
Returns the offset (in bytes) of the Int8Array from the start of its {{jsxref("ArrayBuffer")}}. Fixed at construction time and thus read only.
+
{{jsxref("TypedArray.prototype.length", "Int8Array.prototype.length")}} {{readonlyInline}}
+
Returns the number of elements hold in the Int8Array. Fixed at construction time and thus read only.
+
+ +

方法

+ +
+
{{jsxref("TypedArray.copyWithin", "Int8Array.prototype.copyWithin()")}}
+
Copies a sequence of array elements within the array. See also {{jsxref("Array.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.entries", "Int8Array.prototype.entries()")}}
+
Returns a new Array Iterator object that contains the key/value pairs for each index in the array. See also {{jsxref("Array.prototype.entries()")}}.
+
{{jsxref("TypedArray.every", "Int8Array.prototype.every()")}}
+
Tests whether all elements in the array pass the test provided by a function. See also {{jsxref("Array.prototype.every()")}}.
+
{{jsxref("TypedArray.fill", "Int8Array.prototype.fill()")}}
+
Fills all the elements of an array from a start index to an end index with a static value. See also {{jsxref("Array.prototype.fill()")}}.
+
{{jsxref("TypedArray.filter", "Int8Array.prototype.filter()")}}
+
Creates a new array with all of the elements of this array for which the provided filtering function returns true. See also {{jsxref("Array.prototype.filter()")}}.
+
{{jsxref("TypedArray.find", "Int8Array.prototype.find()")}}
+
Returns the found value in the array, if an element in the array satisfies the provided testing function or undefined if not found. See also {{jsxref("Array.prototype.find()")}}.
+
{{jsxref("TypedArray.findIndex", "Int8Array.prototype.findIndex()")}}
+
Returns the found index in the array, if an element in the array satisfies the provided testing function or -1 if not found. See also {{jsxref("Array.prototype.findIndex()")}}.
+
{{jsxref("TypedArray.forEach", "Int8Array.prototype.forEach()")}}
+
Calls a function for each element in the array. See also {{jsxref("Array.prototype.forEach()")}}.
+
{{jsxref("TypedArray.includes", "Int8Array.prototype.includes()")}} {{experimental_inline}}
+
Determines whether a typed array includes a certain element, returning true or false as appropriate. See also {{jsxref("Array.prototype.includes()")}}.
+
{{jsxref("TypedArray.indexOf", "Int8Array.prototype.indexOf()")}}
+
Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.indexOf()")}}.
+
{{jsxref("TypedArray.join", "Int8Array.prototype.join()")}}
+
Joins all elements of an array into a string. See also {{jsxref("Array.prototype.join()")}}.
+
{{jsxref("TypedArray.keys", "Int8Array.prototype.keys()")}}
+
Returns a new Array Iterator that contains the keys for each index in the array. See also {{jsxref("Array.prototype.keys()")}}.
+
{{jsxref("TypedArray.lastIndexOf", "Int8Array.prototype.lastIndexOf()")}}
+
Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.lastIndexOf()")}}.
+
{{jsxref("TypedArray.map", "Int8Array.prototype.map()")}}
+
返回一个由回调函数的返回值组成的新数组。. See also {{jsxref("Array.prototype.map()")}}.
+
{{jsxref("TypedArray.move", "Int8Array.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
+
{{jsxref("TypedArray.copyWithin", "Int8Array.prototype.copyWithin()")}} 早期的不标准定义。
+
{{jsxref("TypedArray.reduce", "Int8Array.prototype.reduce()")}}
+
从左到右为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。参照 {{jsxref("Array.prototype.reduce()")}}.
+
{{jsxref("TypedArray.reduceRight", "Int8Array.prototype.reduceRight()")}}
+
从右到左为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。参照 {{jsxref("Array.prototype.reduceRight()")}}.
+
{{jsxref("TypedArray.reverse", "Int8Array.prototype.reverse()")}}
+
颠倒数组中元素的排列顺序,即原先的第一个变为最后一个,原先的最后一个变为第一个。参照{{jsxref("Array.prototype.reverse()")}}.
+
{{jsxref("TypedArray.set", "Int8Array.prototype.set()")}}
+
Stores multiple values in the typed array, reading input values from a specified array.
+
{{jsxref("TypedArray.slice", "Int8Array.prototype.slice()")}}
+
抽取当前数组中的一段元素组合成一个新数组。参照{{jsxref("Array.prototype.slice()")}}.
+
{{jsxref("TypedArray.some", "Int8Array.prototype.some()")}}
+
如果数组中至少有一个元素满足测试函数,则返回 true,否则返回 false。参照 {{jsxref("Array.prototype.some()")}}.
+
{{jsxref("TypedArray.sort", "Int8Array.prototype.sort()")}}
+
对数组元素进行排序,并返回当前数组. 参照{{jsxref("Array.prototype.sort()")}}.
+
{{jsxref("TypedArray.subarray", "Int8Array.prototype.subarray()")}}
+
返回一个以给定的初始结束位置裁剪的Int8Array数组.
+
{{jsxref("TypedArray.values", "Int8Array.prototype.values()")}}
+
返回一个数组迭代器对象,该迭代器会包含所有数组元素的值。. 参照 {{jsxref("Array.prototype.values()")}}.
+
{{jsxref("TypedArray.toLocaleString", "Int8Array.prototype.toLocaleString()")}}
+
返回一个由所有数组元素组合而成的本地化后的字符串. See also {{jsxref("Array.prototype.toLocaleString()")}}.
+
{{jsxref("TypedArray.toString", "Int8Array.prototype.toString()")}}
+
返回一个由所有数组元素组合而成的字符串.参照 {{jsxref("Array.prototype.toString()")}}.
+
{{jsxref("TypedArray.@@iterator", "Int8Array.prototype[@@iterator]()")}}
+
此方法返回一个带有数组内所有元素的迭代器对象,同Int8Array.prototype.values 。
+
+ +

示例

+ +
// 以长度参数构造对象
+var int8 = new Int8Array(2);
+int8[0] = 42;
+console.log(int8[0]); // 42
+console.log(int8.length); // 2
+console.log(int8.BYTES_PER_ELEMENT); // 1
+
+// 以数组构造对象
+var arr = new Int8Array([21,31]);
+console.log(arr[1]); // 31
+
+// 从另一数组构造对象
+var x = new Int8Array([21, 31]);
+var y = new Int8Array(x);
+console.log(y[0]); // 21
+
+// 从ArrayBuffer构造对象
+var buffer = new ArrayBuffer(8);
+var z = new Int8Array(buffer, 1, 4);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态评论
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}已被 ECMAScript 6取代。
{{SpecName('ES6', '#table-49', 'TypedArray constructors')}}{{Spec2('ES6')}}ECMA 标准中构造对象时 new 关键字为必需。
{{SpecName('ESDraft', '#table-49', 'TypedArray constructors')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
功能ChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support7.0{{ CompatGeckoDesktop("2") }}1011.65.1
new is required{{CompatUnknown}}{{ CompatGeckoDesktop("44") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile("2") }}1011.64.2
new is required{{CompatUnknown}}{{CompatUnknown}}{{ CompatGeckoMobile("44") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

兼容性说明

+ +

自 ECMAScript 2015 (ES6)施行, Int8Array 需要使用{{jsxref("Operators/new", "new")}} 构造. 从当前版本开始,不加new而便调用Int8Array 构造器方法, 将报出 {{jsxref("TypeError")}} 错误.

+ +
var dv = Int8Array([1, 2, 3]);
+// TypeError: calling a builtin Int8Array constructor
+// without new is forbidden
+ +
var dv = new Int8Array([1, 2, 3]);
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/internalerror/index.html b/files/zh-cn/web/javascript/reference/global_objects/internalerror/index.html new file mode 100644 index 0000000000..e0f98013f9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/internalerror/index.html @@ -0,0 +1,123 @@ +--- +title: InternalError +slug: Web/JavaScript/Reference/Global_Objects/InternalError +tags: + - InternalError + - 内部错误 +translation_of: Web/JavaScript/Reference/Global_Objects/InternalError +--- +
{{JSRef}} {{non-standard_header}}
+ +

InternalError 对象表示出现在JavaScript引擎内部的错误。 例如: "InternalError: too much recursion"(内部错误:递归过深)。

+ +

语法

+ +
new InternalError([message[, fileName[, lineNumber]]])
+ +

参数

+ +
+
message
+
可选。 人类可读的错误描述信息。
+
fileName {{non-standard_inline}}
+
可选。触发该错误的代码所在文件的文件名。
+
lineNumber {{non-standard_inline}}
+
可选。触发该错误的代码所在的代码行号。
+
+ +

描述

+ +

当JavaScript引擎出现内部错误时将会抛出InternalError。

+ +

示例场景通常为某些成分过大,例如:

+ + + +

属性

+ +
+
{{jsxref("InternalError.prototype")}}
+
允许向InternalError对象添加属性。
+
+ +

方法

+ +

全局 InternalError 对象自身不包含任何方法,但从原型链中继承了一些方法.

+ +

InternalError 实例

+ +

属性

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError/prototype', '属性')}}
+ +

方法

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError/prototype', '方法')}}
+ +

规范

+ +

尚未成为任何规范的一部分。

+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/collator/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/collator/index.html new file mode 100644 index 0000000000..640bb0b9e4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/collator/index.html @@ -0,0 +1,177 @@ +--- +title: Intl.Collator +slug: Web/JavaScript/Reference/Global_Objects/Intl/Collator +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/Collator +--- +
{{JSRef}}
+ +

Intl.Collator 是用于语言敏感字符串比较的 collators构造函数。

+ +
{{EmbedInteractiveExample("pages/js/intl-collator.html")}}
+ + + +

语法

+ +
new Intl.Collator([locales[, options]])
+Intl.Collator.call(this[, locales[, options]])
+ +

参数

+ +
+
locales
+
+

可选. 缩写语言代码 (BCP 47 language tag, 例如: cmn-Hans-CN) 的字符串或者这些字符串组成的数组. 关于参数 locales 的一般形式和解释请参见{{jsxref("Global_Objects/Intl", "Intl page", "#Locale_identification_and_negotiation", 1)}}. 下面的这些 Unicode 扩展键也是被允许的:

+ +
+
co
+
某些区域设置的变体归类。 可能的值包括:“big5han”,“dict”,“direct”,“ducet”,“gb2312”,“phonebk”,“phonetic”,“pinyin”,“reformed”,“searchjl”,“stroke” “,”unihan“。值“standard” 和 “search” 被忽略; 它们被 options 属性用法替换(详见下文)。
+
kn
+
是否应使用数字对照,使得 “1”<“2”<“10”。 可能的值为 “true” 和 “false”。 此选项可以通过 options 属性或通过 Unicode 扩展 key 设置; 如果两者都提供,options 属性优先。
+
kf
+
首先排序大写或者小写。可能的值为 “upper”,“lower” 或 “false”(使用区域设置的默认值)。 此选项可以通过 options 属性或通过 Unicode 扩展 key 设置; 如果两者都提供,options 属性优先。
+
+
+
options
+
+

可选. 包含一些或所有的下面属性的对象:

+ +
+
localeMatcher
+
使用的 local 的匹配算法. 可能的值有 "lookup" 和 "best fit"; 默认值是 "best fit". 有关此选项的信息, 请参见{{jsxref("Global_Objects/Intl", "Intl page", "#Locale_negotiation", 1)}}.
+
usage
+
比较是用于排序还是用于搜索匹配的字符串。 可能的值为 “sort” 和 “search”; 默认为 “sort”。
+
sensitivity
+
+

字符串中的哪些差异应导致结果值为非零(non-zero)。 可能的值有:

+ +
    +
  • "base": 只有字母不同的字母比较不相等。例子: a ≠ b, a = á, a = A。
  • +
  • "accent": 只有不同的基本字母或重音符号和其他变音符号的字符串比较为不相等。 例如: a ≠ b, a ≠ á, a = A。
  • +
  • "case": 只有不同的基本字母或大小写的字符串比较不相等。 Examples: a ≠ b, a = á, a ≠ A。
  • +
  • "variant": 字符串的字母,口音和其他变音符号、或不同大小写比较不相等。 也可以考虑其他差异。例如: a ≠ b, a ≠ á, a ≠ A.
  • +
+ +

"variant" 的默认值使用 "sort"; 它的 locale 依赖于使用 "search".

+
+
ignore­Punctua­tion
+
是否应忽略标点。 可能的值为 true 和 false; 默认值为 false。
+
numeric
+
是否应使用数字对照,使得 “1”<“2”<“10”。 可能的值为 “true” 和 “false”。默认值为 “false” 。 此选项可以通过 options 属性或通过 Unicode 扩展 key 设置; 如果两者都提供,options 属性优先。实现不需要支持此属性。
+
caseFirst
+
首先排序大写或者小写。可能的值为 “upper”,“lower” 或 “false”(使用区域设置的默认值)。 此选项可以通过 options 属性或通过 Unicode 扩展 key 设置; 如果两者都提供,options 属性优先。实现不需要支持此属性。
+
+
+
+ +

描述

+ +

Intl.Collator 类有一下属性和方法

+ +

属性

+ +
+
{{jsxref("Collator.prototype", "Intl.Collator.prototype")}}
+
允许向所有对象添加属性。
+
+ +

方法

+ +
+
{{jsxref("Collator.supportedLocalesOf", "Intl.Collator.supportedLocalesOf()")}}
+
返回包含所支持的所提供语言环境的数组的数组,而不必回退到运行时的默认语言环境。
+
+ +

Collator 实例

+ +

属性

+ +

Collator 实例从其原型继承以下属性:

+ +
{{page('en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator/prototype', 'Properties')}}
+ +

方法

+ +

Collator 实例从其原型继承以下方法:

+ +
{{page('en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator/prototype', 'Methods')}}
+ +

例子

+ +

基本用法

+ +

以下示例演示在另一个之前,之后或同级别发生的字符串的不同潜在结果:

+ +
console.log(new Intl.Collator().compare('a', 'c')); // → a negative value
+console.log(new Intl.Collator().compare('c', 'a')); // → a positive value
+console.log(new Intl.Collator().compare('a', 'a')); // → 0
+
+ +

请注意,上述代码中显示的结果可能会因浏览器和浏览器版本而异。 这是因为值是实现特定的。 也就是说,规范仅需要前后值为负和正。

+ +

使用 locales

+ +

{{jsxref("Collator.prototype.compare()")}} 提供的结果在不同语言之间有所不同。为了获得用于您的应用程序的用户界面的语言格式,请确保设定了语言(可能还有一些回退语言)参数:

+ +
// 德语中, ä 使用 a 的排序
+console.log(new Intl.Collator('de').compare('ä', 'z'));
+// → 一个负值
+
+// 瑞典语中, ä 在 z 的后面
+console.log(new Intl.Collator('sv').compare('ä', 'z'));
+// → 一个正值
+
+ +

使用 options

+ +

{{jsxref("Collator.prototype.compare()")}} 提供的结果可以使用 options 参数自定义:

+ +
// 德语中, ä 使用 a 作为基本字母
+console.log(new Intl.Collator('de', { sensitivity: 'base' }).compare('ä', 'a'));
+// → 0
+
+// 瑞典语中, ä 和 a 是单独的基本字母
+console.log(new Intl.Collator('sv', { sensitivity: 'base' }).compare('ä', 'a'));
+// → 一个正值
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES Int 1.0', '#sec-10.1', 'Intl.Collator')}}{{Spec2('ES Int 1.0')}}Initial definition.
{{SpecName('ES Int 2.0', '#sec-10.1', 'Intl.Collator')}}{{Spec2('ES Int 2.0')}} 
{{SpecName('ES Int Draft', '#collator-objects', 'Intl.Collator')}}{{Spec2('ES Int Draft')}} 
+ +

浏览器兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.Intl.Collator")}}

+
+
+ +

参见

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl', 'See_also')}}
diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/index.html new file mode 100644 index 0000000000..ef43816d44 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/index.html @@ -0,0 +1,286 @@ +--- +title: Intl.DateTimeFormat +slug: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat +--- +
{{JSRef}}
+ +
Intl.DateTimeFormat是根据语言来格式化日期和时间的对象的构造器。
+ +
{{EmbedInteractiveExample("pages/js/intl-datetimeformat.html")}}
+ + + +

语法

+ +
new Intl.DateTimeFormat([locales[, options]])
+Intl.DateTimeFormat.call(this[, locales[, options]])
+ +

参数

+ +
+
locales
+
+

可选.缩写语言代码(BCP 47 language tag,例如:cmn-Hans-CN)的字符串或者这些字符串组成的数组. 关于参数locales的一般形式和解释请参见{{jsxref("Global_Objects/Intl", "Intl page", "#Locale_identification_and_negotiation", 1)}}. 下面的这些Unicode扩展键也是被允许的:

+ +

译者注:下面这两种扩展的使用方式是language[-scripts][-region]-u-nu-* 和 language[-scripts][-region]-u-ca-* ,例如:zh-u-nu-hanidec(表示中文十进制数字) 和 zh-u-ca-chinese(表示中国日历,比如壬辰年冬月8日) ,也可以 nu 和 ca 组合使用 比如 使用 zh-u-ca-chinese-nu-hanidec 格式化Date.now()的返回值类似于"丙申年冬月九日"

+ +

nu

+ +
+
编号系统. 可能的值包括: "arab", "arabext", "bali", "beng", "deva", "fullwide", "gujr", "guru", "hanidec", "khmr", "knda", "laoo", "latn", "limb", "mlym", "mong", "mymr", "orya", "tamldec", "telu", "thai", "tibt".
+
ca
+
日历. 可能的值包括: "buddhist", "chinese", "coptic", "ethioaa", "ethiopic", "gregory", "hebrew", "indian", "islamic", "islamicc", "iso8601", "japanese", "persian", "roc".
+
+
+
options
+
+

可选. 包含一些或所有的下面属性的类:

+ +
+
localeMatcher
+
使用的local的匹配算法. 可能的值有"lookup"和"best fit"; 默认值是 "best fit". 有关此选项的信息, 请参见{{jsxref("Global_Objects/Intl", "Intl page", "#Locale_negotiation", 1)}}.
+
timeZone
+
使用的时区. 这唯一的值实现必须被标准世界时间(UTC)所识别。默认值是运行时的默认时区. IANA time zone database中的时区名称可能会被识别, 例如"Asia/Shanghai", "Asia/Kolkata", "America/New_York".
+
hour12
+
是否使用12小时时间制(而不是24小时的时间). 可能的值是true 或 false; 默认值是根据locale来自动决定的(译者注:中国地区的默认值为true).
+
formatMatcher
+
format的匹配算法.可能的值有"basic"和"best fit";默认值是"best fit".有关此属性使用的信息,参见以下段落。
+
+

日期时间插件被格式化输出时可以使用的属性集合描述。实现需要支持是以下子集中的其中一个(译者注:当weekday,year等这些属性一个也不使用的时候,在cmn-Hans-CN中相当于使用集合year, month, day, hour, minute, second并且它们的值都是numeric):

+
+
+ +
    +
  • weekday, year, month, day, hour, minute, second
  • +
  • weekday, year, month, day
  • +
  • year, month, day
  • +
  • year, month
  • +
  • month, day
  • +
  • hour, minute, second
  • +
  • hour, minute
  • +
+ +

实现可能支持其他的子集,并通过对所有可用的子集对比找到最匹配的子集。通过 formatMatcher属性可以设置两种算法用于对比和选择子集:  完全匹配"basic"算法  和 一种依赖于“best fit”算法的实现.

+ +
+
weekday
+
工作日的展现方式.可能的值有 "narrow", "short", "long".
+
era
+
纪元的展现方式. 可能的值有 "narrow", "short", "long".
+
year
+
年的展现方式.  可能的值有 "numeric", "2-digit".
+
month
+
月的展现方式. 可能的值有 "numeric", "2-digit", "narrow", "short", "long".
+
day
+
日的展现方式.可能的值有 "numeric", "2-digit".
+
hour
+
时的展现方式.可能的值有 "numeric", "2-digit".
+
minute
+
分钟的展现方式.可能的值有 "numeric", "2-digit".
+
second
+
秒的展现方式. 可能的值有"numeric", "2-digit".
+
timeZoneName
+
时区名称的展现方式.可能的值有 "short", "long".
+
+ +

每个日期时间组件属性的默认值都是{{jsxref("undefined")}},但是若所有的组件属性都是{{jsxref("undefined")}},那么year, month, and day 的值就都被认为是"numeric".

+
+
+ +

描述

+ +

属性

+ +
+
{{jsxref("DateTimeFormat.prototype", "Intl.DateTimeFormat.prototype")}}
+
允许将属性添加到所有对象上。
+
+ +

方法

+ +
+
{{jsxref("DateTimeFormat.supportedLocalesOf", "Intl.DateTimeFormat.supportedLocalesOf()")}}
+
Returns an array containing those of the provided locales that are supported without having to fall back to the runtime's default locale.
+
+ +

DateTimeFormat 实例

+ +

属性

+ +

DateTimeFormat实例集成以下原型的属性:

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/prototype', 'Properties')}}
+ +

方法

+ +

DateTimeFormat实例集成以下原型的方法:

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/prototype', 'Methods')}}
+ +

实例

+ +

使用 DateTimeFormat

+ +

不指定locale时,DateTimeFormat使用默认的locale 和 默认的 options

+ +
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
+
+//参数未填时使用默认的locale和默认的时区
+console.log(new Intl.DateTimeFormat().format(date));
+//如果是在洛杉矶那么值为 → "12/19/2012"
+
+ +

使用locales

+ +

这个例子显示了本地化日期和时间格式的一些变化。为了获得用于您的应用程序的用户界面的语言格式,请确保使用locales参数确保指定语言(可能还有一些回退语言):

+ +
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
+
+// 下面是假定的所在时区
+// 洛杉矶(America/Los_Angeles for the US)
+
+// 美式英语(US English) 使用  month-day-year 格式
+console.log(new Intl.DateTimeFormat('en-US').format(date));
+// → "12/19/2012"
+
+// 英式英语(British English) 使用 day-month-year 格式
+console.log(new Intl.DateTimeFormat('en-GB').format(date));
+// → "20/12/2012"
+
+// 韩国使用 year-month-day 格式
+console.log(new Intl.DateTimeFormat('ko-KR').format(date));
+// → "2012. 12. 20."
+
+//大部分阿拉伯国家使用阿拉伯字母(real Arabic digits)
+console.log(new Intl.DateTimeFormat('ar-EG').format(date));
+// → "٢٠‏/١٢‏/٢٠١٢"
+
+//在日本,应用可能想要使用日本日历,
+//2012 是平成24年(平成是是日本天皇明仁的年号,由1989年1月8日起开始计算直至现在)
+console.log(new Intl.DateTimeFormat('ja-JP-u-ca-japanese').format(date));
+// → "平成24/12/20"
+
+//当请求一个语言可能不支持,如巴厘(ban),若有备用的语言印尼语(id),
+//那么将使用印尼语(id)
+console.log(new Intl.DateTimeFormat(['ban', 'id']).format(date));
+// → "20/12/2012"
+
+ +

使用options

+ +

可以使用 options 参数来自定义 日期时间格式化方法返回的字符串。

+ +
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
+
+//请求参数(options)中包含参数星期(weekday),并且该参数的值为长类型(long)
+var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
+console.log(new Intl.DateTimeFormat('de-DE', options).format(date));
+// → "Donnerstag, 20. Dezember 2012"
+
+// 一个应用使用 世界标准时间(UTC),并且UTC使用短名字(short)展示
+options.timeZone = 'UTC';
+options.timeZoneName = 'short';//若不写这一行那么仍然显示的是世界标准时间;但是GMT三个字母不会显示
+console.log(new Intl.DateTimeFormat('en-US', options).format(date));
+// → "Thursday, December 20, 2012, GMT"
+
+// 有时你想变得更精确
+options = {
+  hour: 'numeric', minute: 'numeric', second: 'numeric',
+  timeZoneName: 'short'
+};
+console.log(new Intl.DateTimeFormat('en-AU', options).format(date));
+// → "2:00:00 pm AEDT"
+
+// 使用24小时制
+options = {
+  year: 'numeric', month: 'numeric', day: 'numeric',
+  hour: 'numeric', minute: 'numeric', second: 'numeric',
+  hour12: false
+};
+console.log(date.toLocaleString('en-US', options));
+// → "12/19/2012, 19:00:00"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES Int 1.0', '#sec-12.1', 'Intl.DateTimeFormat')}}{{Spec2('ES Int 1.0')}}Initial definition.
{{SpecName('ES Int 2.0', '#sec-12.1', 'Intl.DateTimeFormat')}}{{Spec2('ES Int 2.0')}} 
{{SpecName('ES Int Draft', '#datetimeformat-objects', 'Intl.DateTimeFormat')}}{{Spec2('ES Int Draft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome("24")}}{{CompatGeckoDesktop("29")}}{{CompatIE("11")}}{{CompatOpera("15")}}{{CompatSafari("10")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("26")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatSafari("10")}}
+
+ +

相关链接

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl', 'See_also')}}
diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html new file mode 100644 index 0000000000..d8cb843c33 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html @@ -0,0 +1,119 @@ +--- +title: Intl.DateTimeFormat.prototype +slug: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat +--- +
{{JSRef}}
+ +

Intl.DateTimeFormat.prototype表示 {{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}构造函数的原型对象。

+ +

{{js_property_attributes(0, 0, 0)}} 

+ +

描述

+ +

参见 {{jsxref("DateTimeFormat")}}来看Intl.DateTimeFormat实例的一个描述。

+ +

{{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}} 实例继承自Intl.DateTimeFormat.prototype. 对原型对象的修改都继承自{{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}实例。

+ +

属性

+ +
+
Intl.DateTimeFormat.prototype.constructor
+
请参考 {{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}.
+
{{jsxref("DateTimeFormat.format", "Intl.DateTimeFormat.prototype.format")}}
+
Getter; 返回一个{{jsxref("DateTimeFormat", "DateTimeFormat")}}对象的根据locale和格式化参数格式化日期的函数。
+
+ +

方法

+ +
+
{{jsxref("DateTimeFormat.formatToParts", "Intl.DateTimeFormat.prototype.formatToParts()")}}
+
Returns an {{jsxref("Array")}} of objects representing the date string in parts that can be used for custom locale-aware formatting.
+
{{jsxref("DateTimeFormat.resolvedOptions", "Intl.DateTimeFormat.prototype.resolvedOptions()")}}
+
返回一个新的属性对象,反射出在对象初始化过程中计算出的locale和options的各个值。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES Int 1.0', '#sec-12.2.1', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int 1.0')}}初始定义
{{SpecName('ES Int 2.0', '#sec-12.2.1', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int 2.0')}} 
{{SpecName('ES Int Draft', '#sec-Intl.DateTimeFormat.prototype', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int Draft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome("24")}}{{CompatGeckoDesktop("29")}}{{CompatIE("11")}}{{CompatOpera("15")}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("26")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/displaynames/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/displaynames/index.html new file mode 100644 index 0000000000..06b7cf130b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/displaynames/index.html @@ -0,0 +1,28 @@ +--- +title: Intl.DisplayNames +slug: Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames +--- +

{{JSRef}} Intl.DisplayNames 是一个对象构造器,它支持语言、区域和脚本显示名称的一致翻译。

+ +

语法

+ +
new Intl.DisplayNames([locales[, options]]) 
+
+ +

规范

+ + + + + + + + + + + + + + +
规范版本规范状态注解
Intl.DisplayNames ConstructorStage 3
diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/getcanonicallocales/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/getcanonicallocales/index.html new file mode 100644 index 0000000000..78ee477634 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/getcanonicallocales/index.html @@ -0,0 +1,72 @@ +--- +title: Intl.getCanonicalLocales() +slug: Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales +tags: + - 区域语言代码 + - 去重 +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales +--- +
{{JSRef}}
+ +

Intl.getCanonicalLocales() 方法返回一个数组,数组包含规范的区域语言代码,重复的元素将会被去除,每一个元素都会被验证为格式有效的区域语言代码。

+ +
{{EmbedInteractiveExample("pages/js/intl-getcanonicallocales.html")}}
+ + + +

Syntax

+ +
Intl.getCanonicalLocales(locales)
+ +

参数

+ +
+
locales
+
想要规范化的字符串数组。
+
+ +

Return value

+ +

一个包含规范区域语言代码的数组。

+ +

例子

+ +
Intl.getCanonicalLocales('EN-US'); // ["en-US"]
+Intl.getCanonicalLocales(['EN-US', 'Fr']); // ["en-US", "fr"]
+
+Intl.getCanonicalLocales('EN_US');
+// RangeError:'EN_US' is not a structurally valid language tag
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES Int Draft', '#sec-intl.getcanonicallocales', 'Intl.getCanonicalLocales')}}{{Spec2('ES Int Draft')}}Initial definition
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.builtins.Intl.getCanonicalLocales")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/index.html new file mode 100644 index 0000000000..165a332206 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/index.html @@ -0,0 +1,132 @@ +--- +title: Intl +slug: Web/JavaScript/Reference/Global_Objects/Intl +tags: + - JavaScript + - 国际化 +translation_of: Web/JavaScript/Reference/Global_Objects/Intl +--- +
{{JSRef}}
+ +

Intl 对象是 ECMAScript 国际化 API 的一个命名空间,它提供了精确的字符串对比、数字格式化,和日期时间格式化。{{jsxref("Collator")}},{{jsxref("NumberFormat")}} 和 {{jsxref("DateTimeFormat")}} 对象的构造函数是 Intl 对象的属性。本页文档内容包括了这些属性,以及国际化使用的构造器和其他语言的方法等常见的功能。

+ +

属性

+ +
+
{{jsxref("Global_Objects/Collator", "Intl.Collator")}}
+
collators的构造函数,用于启用对语言敏感的字符串比较的对象。
+
{{jsxref("Global_Objects/DateTimeFormat", "Intl.DateTimeFormat")}}
+
用于启用语言敏感的日期和时间格式的对象的构造函数。
+
{{jsxref("Global_Objects/ListFormat", "Intl.ListFormat")}}
+
Constructor for objects that enable language-sensitive list formatting.
+
{{jsxref("Global_Objects/NumberFormat", "Intl.NumberFormat")}}
+
用于启用语言敏感数字格式的对象的构造函数。
+
{{jsxref("Global_Objects/PluralRules", "Intl.PluralRules")}}
+
用于启用多种敏感格式和多种语言语言规则的对象的构造函数。
+
{{jsxref("Global_Objects/RelativeTimeFormat", "Intl.RelativeTimeFormat")}}
+
Constructor for objects that enable language-sensitive relative time formatting.
+
+ +

方法

+ +
+
{{jsxref("Intl.getCanonicalLocales()")}}
+
返回规范区域名称(canonical locale name)。
+
+ +

语言区域识别和判定

+ +

国际化的构造函数和其他构造函数的几个语言敏感的方法(可参考下方的{{anch("See_also", "参见")}})一样,使用同样的模式来识别语言区域和确定使用哪一种语言格式:他们都接收 localesoptions 参数,使用 options.localeMatcher 属性指定的一个算法来对比应用请求的和支持的语言区域,来确定使用哪一个语言区域。

+ +

locales 参数

+ +

locales 参数必须是一个 BCP 47 语言标记的字符串,或者是一个包括多个语言标记的数组。如果 locales 参数未提供或者是 undefined,便会使用运行时默认的 locale。

+ +

一个 BCP 47 语言标记代表了一种语言或者区域(两者没有很大的区别)。在其最常见的格式中,它以这样的顺序囊括了这些内容:语言代码,脚本代码,和国家代码,全部由连字符分隔开。例如:

+ + + +

在 BCP 47 中表示语言,脚本,国家(区域)和变体(少用)的语言子标记含义可以在 IANA 语言子标记注册中找到。

+ +

BCP 47 也支持扩展,其中一个和 JavaScript 国际化方法相关的是:"u"(Unicode)扩展。它可以用于请求一个自定义区域特定行为的 {{jsxref("Collator")}},{{jsxref("NumberFormat")}},或者 {{jsxref("DateTimeFormat")}} 对象。例如:

+ + + +

语言区域判定

+ +

locales 参数,在除去所有的 Unicode 扩展之后,会被转化成来自应用的优先请求。运行时拿它和可用的语言区域做对比然后选择出最合适的一个。有两种匹配算法:“查找” 匹配遵循 BCP 47 中指定的查找算法;“最佳命中” 匹配器会让运行时至少提供一个语言区域,但合适请求的结果可能会比查找算法的要多。如果应用没有提供一个 locales 参数,或者运行时没有一个匹配请求的语言区域,那么会使用运行时默认的语言区域。匹配器可以使用 options 参数的一个属性来进行选择(见下方)。

+ +

如果选中的语言标记有一个 Unicode 扩展子字符串,这个扩展会用于自定义构造对象或者方法的行为。每一个构造函数或者方法仅支持 Unicode 扩展定义的 key 的一个子集,和依赖于语言标记的支持的值。例如,“co”这个 key(collation)只在 {{jsxref("Collator")}} 中支持,它的值 “phonebk” 只在德语中支持。

+ +

options 参数

+ +

options 参数必须是一个对象,其属性值在不同的构造函数和方法中会有所变化。如果 options 参数未提供或者为 undefined,所有的属性值则使用默认的。

+ +

所有语言敏感的构造函数和方法都支持的一个属性是:localeMatcher 属性,它的值必须是字符串 “lookup” 或者 “best fit”,用于选择上边描述的语言区域匹配算法。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES Int 1.0', '#sec-8', 'Intl')}}{{Spec2('ES Int 1.0')}}Initial definition.
{{SpecName('ES Int 2.0', '#sec-8', 'Intl')}}{{Spec2('ES Int 2.0')}} 
{{SpecName('ES Int Draft', '#intl-object', 'Intl')}}{{Spec2('ES Int Draft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Intl")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/listformat/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/listformat/index.html new file mode 100644 index 0000000000..c80d0bca89 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/listformat/index.html @@ -0,0 +1,115 @@ +--- +title: Intl.ListFormat +slug: Web/JavaScript/Reference/Global_Objects/Intl/ListFormat +tags: + - Intl + - JavaScript + - ListFormat + - 列表格式化 +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/ListFormat +--- +

{{JSRef}}

+ +

Intl.ListFormat 是一个语言相关的列表格式化构造器。

+ +
{{EmbedInteractiveExample("pages/js/intl-listformat.html")}}
+ + + +

语法

+ +
new Intl.ListFormat([locales[, options]])
+
+ +

参数

+ +
+
locales
+
+

可选的.。符合 BCP 47 语言标注的字符串或字符串数组。locales 参数的一般形式和相关解释,请参阅 {{jsxref("Global_Objects/Intl", "Intl page", "#Locale_identification_and_negotiation", 1)}}.

+
+
options
+
可选的。 拥有下面所列属性中任意几个或全部的对象: +
    +
  • localeMatcher
    + 指定要使用的本地匹配算法。可选的值有"lookup" 和 "best fit";默认情况下使用"best fit"。该参数的更多信息,请参考Intl page.
  • +
  • type
    + 消息输出的格式。可选的值有用于替代基于“且”关系列表的"conjunction" (默认值, 例如: A, B, and C), 或者用于替代基于“或”关系列表的 "disjunction"(例如: A, B, or C),以及用于替代带计量单位的值列表的"unit" (例如: 5 pounds, 12 ounces).
  • +
  • style
    + 被格式化消息的长度。可选值有:"long" (默认值,例如: A, B, and C)、"short" 或者 "narrow" (例如: A, B, C)。 当style 的值为narrow时,type 属性的值只能取值unit。
  • +
+
+
+ +

描述

+ +

属性

+ +
+
{{jsxref("ListFormat.prototype", "Intl.ListFormat.prototype")}}
+
允许增加一个属性到列表中的所有对象。
+
+ +

方法

+ +
+
{{jsxref("ListFormat.supportedLocalesOf", "Intl.ListFormat.supportedLocalesOf()")}}
+
返回一个包含指定的被支持区域设置的数组,没有时使用运行环境默认区域设置
+
+ +

示例

+ +

使用 format

+ +

下面的例子展示了用英语语言怎么去创建一个列表格式化器。

+ +
const list = ['Motorcycle', 'Bus', 'Car'];
+
+ console.log(new Intl.ListFormat('en-GB', { style: 'long', type: 'conjunction' }).format(list));
+// > Motorcycle, Bus and Car
+
+ console.log(new Intl.ListFormat('en-GB', { style: 'short', type: 'disjunction' }).format(list));
+// > Motorcycle, Bus or Car
+
+ console.log(new Intl.ListFormat('en-GB', { style: 'narrow', type: 'unit' }).format(list));
+// > Motorcycle Bus Car
+
+ +

使用 formatToParts

+ +

下面的例子展示了如何创建一个返回被格式化部分的列表格式化器。

+ +
const list = ['Motorcycle', 'Bus', 'Car'];
+console.log(new Intl.ListFormat('en-GB', { style: 'long', type: 'conjunction' }).formatToParts(list));
+
+// > [ { "type": "element", "value": "Motorcycle" }, { "type": "literal", "value": ", " }, { "type": "element", "value": "Bus" }, { "type": "literal", "value": ", and " }, { "type": "element", "value": "Car" } ];
+
+ +

说明

+ + + + + + + + + + + + + + +
SpecificationStatusComment
Intl.ListFormat proposalStage 3 
+ +

浏览器支持

+ +
+ + +

{{Compat("javascript.builtins.Intl.ListFormat")}}

+
+ +

参考地址

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl', 'See_also')}}
diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/locale/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/locale/index.html new file mode 100644 index 0000000000..2714245ace --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/locale/index.html @@ -0,0 +1,105 @@ +--- +title: Intl.Locale +slug: Web/JavaScript/Reference/Global_Objects/Intl/Locale +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/Locale +--- +
{{JSRef}}
+ +

Intl.Locale 对象是 Intl 对象的标准内置属性,用于表示 Unicode 区域标识。

+ +
{{EmbedInteractiveExample("pages/js/intl-locale.html")}}
+ +

描述

+ +

Intl.Locale 对象是为了更便捷地处理 Unicode 区域设置。Unicode 使用字符串作为区域识别标识。区域标识符由语言标识符扩展标记组成。语言标识符是区域(locale)的核心,包含了语言、脚本和地域子标记(region subtags)。有关区域设置的其他信息体现在可选的扩展标记中。扩展标记保存有关区域设置方面的信息,例如日历类型、时钟类型和编号系统类型。

+ +

传统上,Intl 接口像 Unicode 一样使用字符串来表示区域设置,这是一个简单而轻量且效果好的解决方案。但是,添加一个Locale 类可以更容易地解析和操作语言、脚本、区域以及扩展标记。

+ +

构造函数

+ +
+
{{jsxref("Locale/Locale", "Intl.Locale()")}}
+
实例化一个 Locale 对象。
+
+ +

实例属性

+ +
+
Intl.Locale.prototype.baseName
+
Returns basic, core information about the Locale in the form of a substring of the complete data string.
+
Intl.Locale.prototype.calendar
+
Returns the part of the Locale that indicates the Locale's calendar era.
+
Intl.Locale.prototype.caseFirst
+
Returns whether case is taken into account for the locale's collation rules.
+
Intl.Locale.prototype.collation
+
Returns the collation type for the Locale, which is used to order strings according to the locale's rules.
+
Intl.Locale.prototype.hourCycle
+
Returns the time keeping format convention used by the locale.
+
Intl.Locale.prototype.language
+
Returns the language associated with the locale.
+
Intl.Locale.prototype.numberingSystem
+
Returns the numeral system used by the locale.
+
Intl.Locale.prototype.numeric
+
Returns whether the locale has special collation handling for numeric characters.
+
Intl.Locale.prototype.region
+
Returns the region of the world (usually a country) associated with the locale.
+
Intl.Locale.prototype.script
+
Returns the script used for writing the particular language used in the locale.
+
+ +

实例方法

+ +
+
Intl.Locale.prototype.maximize()
+
Gets the most likely values for the language, script, and region of the locale based on existing values.
+
Intl.Locale.prototype.minimize()
+
Gets the most likely values for the language, script, and region of the locale based on existing values.
+
Intl.Locale.prototype.toString()
+
Returns the Locale's full locale identifier string.
+
+ +

范例

+ +

基本使用

+ +

很简单,就是需要给{{jsxref("Locale/Locale", "Intl.Locale")}} 构造函数传入一个 locale 标识字符串作为参数:

+ +
let us = new Intl.Locale('zh-Hans-CN');
+ +

使用配置实例化

+ +

构造函数支持传入 object 作为配置,object 中可包含多个配置属性。例如,设置 hourCycle 属性,用于设置您所需要的小时周期类型:

+ +
let zh12hour = new Intl.Locale("zh-Hans-CN", {hourCycle: "h12"});
+console.log(zh12hour.hourCycle); // Prints "h12"
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
Intl.Locale proposalStage 3
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Intl.Locale")}}

+
+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/numberformat/format/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/numberformat/format/index.html new file mode 100644 index 0000000000..4e481052b1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/numberformat/format/index.html @@ -0,0 +1,92 @@ +--- +title: Intl.NumberFormat.prototype.format +slug: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/format +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/format +--- +
{{JSRef}}
+ +

 Intl.NumberFormat.prototype.format 属性返回一个根据{{jsxref("NumberFormat")}}对象的语言环境和格式化选项,来格式化一个数字的getter函数。

+ +
{{EmbedInteractiveExample("pages/js/intl-numberformat-prototype-format.html")}}
+ + + +

语法

+ +
numberFormat.format(number)
+ +

参数

+ +
+
number
+
要格式化的数值。
+
+ +

描述

+ +

该函数返回一个根据{{jsxref("NumberFormat")}}对象的语言环境和格式化选项,来format 一个数字的函数。

+ +

示例

+ +

使用 format

+ +

使用 format 格式化一个单一的货币值, 以俄罗斯为例:

+ +
var options = { style: 'currency', currency: 'RUB' };
+var numberFormat = new Intl.NumberFormat('ru-RU', options);
+console.log(numberFormat.format(654321.987));
+// → "654 321,99 руб."
+
+ +

使用 format 和 map

+ +

使用 format 返回的函数来格式化数组中的所有数字。注意,该函数绑定到所获得的{{jsxref("NumberFormat")}},因此它可以直接传递给{{jsxref("Array.prototype.map")}}。

+ +
var a = [123456.789, 987654.321, 456789.123];
+var numberFormat = new Intl.NumberFormat('es-ES');
+var formatted = a.map(numberFormat.format);
+console.log(formatted.join('; '));
+// → "123.456,789; 987.654,321; 456.789,123"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注解
{{SpecName('ES Int 1.0', '#sec-11.3.2', 'Intl.NumberFormat.prototype.format')}}{{Spec2('ES Int 1.0')}}初始定义
{{SpecName('ES Int 2.0', '#sec-11.3.2', 'Intl.NumberFormat.prototype.format')}}{{Spec2('ES Int 2.0')}} 
{{SpecName('ES Int Draft', '#sec-Intl.NumberFormat.prototype.format', 'Intl.NumberFormat.prototype.format')}}{{Spec2('ES Int Draft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Intl.NumberFormat.format")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/numberformat/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/numberformat/index.html new file mode 100644 index 0000000000..51520c2b83 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/numberformat/index.html @@ -0,0 +1,247 @@ +--- +title: Intl.NumberFormat +slug: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat +tags: + - Intl + - 国际化 +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat +--- +
{{JSRef}}
+ +

Intl.NumberFormat是对语言敏感的格式化数字类的构造器类

+ +

语法

+ +
new Intl.NumberFormat([locales[, options]])
+Intl.NumberFormat.call(this[, locales[, options]])
+
+ +

参数

+ +
+
locales
+
+

可选。缩写语言代码(BCP 47 language tag,例如: cmn-Hans-CN)的字符串或者这些字符串组成的数组. 关于参数 locales 的一般形式和解释请参见Intl page. 下面的这些 Unicode 扩展键也是被允许的:

+ +

译者注:下面扩展的使用方式是language[-scripts][-region]-u-nu-*,例如:zh-u-nu-hanidec(表示中文十进制数字) 

+ +
+
nu
+
要使用的编号系统。可能的值有: "arab", "arabext", "bali", "beng", "deva", "fullwide", "gujr", "guru", "hanidec"(中文十进制数字), "khmr", "knda", "laoo", "latn", "limb", "mlym", "mong", "mymr", "orya", "tamldec", "telu", "thai", "tibt".
+
+
+
options
+
+

可选. 包含一些或所有的下面属性的类:

+ +
    +
  • “decimal” 用于纯数字格式;
  • +
  • “currency” 用于货币格式;
  • +
  • “percent” 用于百分比格式;
  • +
  • “unit” {{Experimental_inline}}  用于单位格式
  • +
+ +
+
localeMatcher
+
使用的 local 的匹配算法. 可能的值有 "lookup 和 "best fit"; 默认值是 "best fit". 有关此选项更多的信息, 请参见 {{jsxref("Global_Objects/Intl", "Intl page", "#Locale_negotiation", 1)}}.
+
style
+
要使用的格式样式,默认为 “decimal”。
+
numberingSystem {{Experimental_inline}}
+
编号系统。可能的值包括:"arab","arabext"," bali","beng","deva","fullwide"," gujr","guru","hanidec","khmr"," knda","laoo", "latn","limb","mlym"," mong","mymr","orya","tamldec"," telu","thai","tibt"。
+
unit{{Experimental_inline}}
+
unit 格式中使用的单位,可能的值为在 UTS #35, Part 2, Section 6 定义的核心单元标识符。已从完整列表中选择了一个单位子集以用于ECMAScript。可以将成对的简单单位与 “ -per-” 连接以组成一个复合单位。没有默认值;如果 style“unit”,必须提供unit 属性。
+
unitDisplay{{Experimental_inline}}
+
unit 格式化中使用的单位格式化样式,默认值为“ short”。
+
+
    +
  • “long” (e.g., 16 litres)
  • +
  • “short“ (e.g., 16 l)
  • +
  • ”narrow“ (e.g., 16l)
  • +
+
+
currency
+
在货币格式化中使用的货币符号. 可能的值是ISO的货币代码 (the ISO 4217 currency codes,) 例如 "USD" 表示美元, "EUR" 表示欧元, 或者 "CNY"是人民币 — 更多请参考 Current currency & funds code list。没有默认值,如果 style“currency”,必须提 currency 属性.
+
currencyDisplay
+
如何在货币格式化中显示货币. 可能的值有 "symbol" 表示使用本地化的货币符号,例如 €, "code" 表示使用国际标准组织货币代码, "name" 表示使用本地化的货币名称,如 "dollar"; 默认值是 "symbol".
+
useGrouping
+
是否使用分组分隔符,如千位分隔符或千/万/亿分隔符。可能的值是 true 和 false,默认值是 true。
+
+ +

下面的属性分为两组:minimumintegerdigitsminimumfractiondigitsmaximumfractiondigits 作为一组,minimumsignificantdigitsmaximumsignificantdigits 作为一组。如果定义了第二组中的任意一个属性,则忽略第一组的设置.

+ +
+
minimumIntegerDigits
+
使用的整数数字的最小数目.可能的值是从1到21,默认值是1.
+
minimumFractionDigits
+
使用的小数位数的最小数目.可能的值是从 0 到 20;默认为普通的数字和百分比格式为 0;默认为货币格式是由 ISO 4217 currency code list  提供 (如果列表中没有提供则值为 2)。
+
maximumFractionDigits
+
使用的小数位数的最大数目。可能的值是从 0 到 20;纯数字格式的默认值是minimumfractiondigits 和 3 中大的那一个;货币格式默认值是minimumfractiondigitsISO 4217 currency code list 中大的那一个(如果列表中没有提供则值为2);百分比格式默认值是 minimumfractiondigits 和 0 中大的那一个。
+
minimumSignificantDigits
+
使用的有效数字的最小数目。可能的值是从1到21;默认值是1。
+
maximumSignificantDigits
+
使用的有效数字的最大数量。可能的值是从1到21;默认是 21.
+
notation{{Experimental_inline}}
+
该号码应显示的格式,默认为 “standard”。 +
    +
  • "standard"  纯数字格式;
  • +
  • "scientific"  返回格式化数字的大小顺序;
  • +
  • "engineering"  当被三除时返回十的指数
  • +
  • "compact" 代表指数的字符串,默认使用 “short” 格式 +
      +
    • "compactDisplay" 仅在 notation“compact” 时使用,采用 “short”(默认)或“long
    • +
    +
  • +
+
+
+
+
+ +

描述

+ +

属性

+ +
+
{{jsxref("NumberFormat.prototype", "Intl.NumberFormat.prototype")}}
+
允许将属性添加到所有对象上。
+
+ +

方法

+ +
+
{{jsxref("NumberFormat.supportedLocalesOf", "Intl.NumberFormat.supportedLocalesOf()")}}
+
返回一个数组包含的那些被提供的可以被支持的locales,运行时的默认的 locale 不会出现在该数组中.
+
+ +

NumberFormat 实例

+ +

属性

+ +

NumberFormat 实例继承一下原型的属性:

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat/prototype', 'Properties')}}
+ +

方法

+ +

NumberFormat 实例继承一下原型的方法:

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat/prototype', 'Methods')}}
+ +

例子

+ +

基本用法

+ +

在不指定locale的基本用法中, 一个使用默认locale和默认options的字符串被返回.

+ +
var number = 3500;
+
+console.log(new Intl.NumberFormat().format(number));
+// 如果在美国英语地区 → '3,500'
+
+ +

使用locales

+ +

这个例子显示了一些本地化的数字格式的一些变化。为了获得用于您的应用程序的用户界面的语言格式,请确保设定了语言(可能还有一些回退语言)参数:

+ +
var number = 123456.789;
+
+// 德语使用逗号作为小数点,使用.作为千位分隔符
+console.log(new Intl.NumberFormat('de-DE').format(number));
+// → 123.456,789
+
+// 大多数阿拉伯语国家使用阿拉伯语数字
+console.log(new Intl.NumberFormat('ar-EG').format(number));
+// → ١٢٣٤٥٦٫٧٨٩
+
+// India uses thousands/lakh/crore separators
+console.log(new Intl.NumberFormat('en-IN').format(number));
+// → 1,23,456.789
+
+// 通过编号系统中的nu扩展键请求, 例如中文十进制数字
+console.log(new Intl.NumberFormat('zh-Hans-CN-u-nu-hanidec').format(number));
+// → 一二三,四五六.七八九
+
+//当请求的语言不被支持,例如巴里,包含一个回滚语言印尼,这时候就会使用印尼语
+console.log(new Intl.NumberFormat(['ban', 'id']).format(number));
+// → 123.456,789
+
+ +

可用的选项

+ +

可用的选项参数,返回的值可以被设置成想要的形式:

+ +
var number = 123456.789;
+
+// 请求一个货币格式
+console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
+// → 123.456,79 €
+
+// the Japanese yen doesn't use a minor unit
+console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
+// → ¥123,457
+
+// 只显示三个有效数字
+console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));
+// → 1,23,000
+
+
+ +

Using notation

+ +
console.log(new Intl.NumberFormat('en-US', { notation: "scientific" }).format(987654321));
+// → 9.877E8
+
+console.log(new Intl.NumberFormat('pt-PT', { notation: "scientific" }).format(987654321));
+// → 9,877E8
+
+console.log(new Intl.NumberFormat('en-GB', { notation: "engineering" }).format(987654321));
+// → 987.654E6
+
+console.log(new Intl.NumberFormat('de', { notation: "engineering" }).format(987654321));
+// → 987,654E6
+
+console.log(new Intl.NumberFormat('zh-CN', { notation: "compact" }).format(987654321));
+// → 9.9亿
+
+console.log(new Intl.NumberFormat('fr', { notation: "compact" , compactDisplay: "long" }).format(987654321));
+// → 988 millions
+
+console.log(new Intl.NumberFormat('en-GB', { notation: "compact" , compactDisplay: "short" }).format(987654321));
+// → 988M
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES Int 1.0', '#sec-11.1', 'Intl.NumberFormat')}}{{Spec2('ES Int 1.0')}}初始定义
{{SpecName('ES Int 2.0', '#sec-11.1', 'Intl.NumberFormat')}}{{Spec2('ES Int 2.0')}}
{{SpecName('ES Int Draft', '#numberformat-objects', 'Intl.NumberFormat')}}{{Spec2('ES Int Draft')}}
+ +

浏览器兼容性

+ +
+ +
{{Compat("javascript.builtins.Intl.NumberFormat")}}
+ +

参见

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl', 'See_also')}}
diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/pluralrules/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/pluralrules/index.html new file mode 100644 index 0000000000..e6da9a523c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/pluralrules/index.html @@ -0,0 +1,150 @@ +--- +title: Intl.PluralRules +slug: Web/JavaScript/Reference/Global_Objects/Intl/PluralRules +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/PluralRules +--- +
{{JSRef}}
+ +

对象的英文请立即获取iTunes多种敏感格式状语从句:多种语言规则对象的构造函数。Intl.PluralRules

+ +

句法

+ +
new Intl.PluralRules([locales[, options]]) Intl.PluralRules.call(this[, locales[, options]])
+
+ +

参数

+ +
+
locales
+
+

可选的。一个带有BCP 47语言标签的字符串或这种字符串的数组。有关参数的一般形式和解释locales,请参阅{{jsxref("Intl", "Intl page", "#Locale_identification_and_negotiation", 1)}}

+
+
options
+
+

可选的,具有部分或全部以下属性的对象:

+ +
+
localeMatcher
+
要使用的语言环境匹配算法。可能的值是"lookup""best fit"; 默认是"best fit"有关此选项的信息,请参阅{{jsxref("Global_Objects/Intl", "Intl page", "#Locale_negotiation", 1)}}
+
type
+
要使用的类型。可能的值是: +
    +
  • "cardinal"对于基数(指的是事物的数量)。这是默认值。
  • +
  • "ordinal" 对于序号(指的是事物的排序或排名,例如英文中的“1st”,“2nd”,“3rd”)。
  • +
+
+
+
+
+ +

描述

+ +

属性

+ +
+
{{jsxref("PluralRules.prototype", "Intl.PluralRules.prototype")}}
+
允许为所有对象添加属性。
+
+ +

方法

+ +
+
{{jsxref("PluralRules.supportedLocalesOf", "Intl.PluralRules.supportedLocalesOf()")}}
+
返回一个数组,其中包含提供的语言环境的支持,而不必回退到运行时的默认语言环境。
+
+ +

PluralRules 实例

+ +

属性

+ +

PluralRules 实例从其原型继承了以下属性:

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules/prototype', 'Properties')}}
+ +

方法

+ +

PluralRules 实例从它们的原型继承了以下方法:

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules/prototype', 'Methods')}}
+ +

例子

+ +

基本用法

+ +

在没有指定语言环境的基本使用中,返回默认语言环境中的格式化字符串和默认选项这有助于区分单数和复数形式,例如“dog”和“dogs”。

+ +
var pr = new Intl.PluralRules();
+
+pr.select(0);
+// → 'other' if in US English locale
+
+pr.select(1);
+// → 'one' if in US English locale
+
+pr.select(2);
+// → 'other' if in US English locale
+ +

运用 locales

+ +

这个例子展示了局部复数规则的一些变化。为了获得应用程序用户界面中使用的语言格式,请确保使用locales参数指定该语言(可能还有一些备用语言)

+ +
// Arabic has different plural rules
+
+new Intl.PluralRules('ar-EG').select(0);
+// → 'zero'
+new Intl.PluralRules('ar-EG').select(1);
+// → 'one'
+new Intl.PluralRules('ar-EG').select(2);
+// → 'two'
+new Intl.PluralRules('ar-EG').select(6);
+// → 'few'
+new Intl.PluralRules('ar-EG').select(18);
+// → 'many'
+ +

运用 options

+ +

可以查询查询结果使用options参数进行自定义,该参数具有一个type您可以设置的属性ordinal这对计算序数指标很有用,例如“第一”,“第二”,“第三”,“第四”,“42”等。

+ +
var pr = new Intl.PluralRules('en-US', { type: 'ordinal' });
+
+pr.select(0);
+// → 'other'
+pr.select(1);
+// → 'one'
+pr.select(2);
+// → 'two'
+pr.select(3);
+// → 'few'
+pr.select(4);
+// → 'other'
+pr.select(42);
+// → 'two'
+ +

规范

+ + + + + + + + + + + + + + +
规范状态评论
国际复数规则草案{{Spec2('ES Int Draft')}}初始定义
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Intl.PluralRules")}}

+
+ +

也可以看看

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl', 'See_also')}}
diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/relativetimeformat/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/relativetimeformat/index.html new file mode 100644 index 0000000000..561af8a1fe --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/intl/relativetimeformat/index.html @@ -0,0 +1,165 @@ +--- +title: Intl.RelativeTimeFormat +slug: Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat +--- +
+
{{JSRef}}
+ +

Intl.RelativeTimeFormat对象启用本地化的相对时间格式。

+ +
{{EmbedInteractiveExample("pages/js/intl-relativetimeformat.html")}}
+ + + +

句法

+ +
new Intl.RelativeTimeFormat([locales[, options]])
+
+ +

参数

+ +
+
locales
+
+

可选的。带有BCP 47语言标记的字符串,或此类字符串的数组。有关参数的一般形式和解释locales,请参阅{{jsxref("Global_Objects/Intl","Intl page","#Locale_identification_and_negotiation",1)}}。

+
+
options
+
可选的。具有以下部分或全部属性的对象: +
    +
  • localeMatcher
    + 要使用的区域设置匹配算法。可能的值是"lookup""best fit"; 默认是"best fit"。有关此选项的信息,请参阅Intl
  • +
  • numeric
    + 输出消息的格式。可能的值是: +
      +
    • "always"(默认,例如,1 day ago),
    • +
    • "auto"(例如yesterday)。该"auto"值允许不必总是在输出中使用数值。
    • +
    +
  • +
  • style
    + 国际化信息的长度。可能的值是: +
      +
    • "long"(默认,例如,in 1 month)
    • +
    • "short"(例如in 1 mo.),
    • +
    • "narrow"(例如in 1 mo.)。狭窄的风格可能类似于某些语言环境的短风格。
    • +
    +
  • +
+
+
+ +

描述

+ +

属性

+ +
+
{{jsxref("RelativeTimeFormat.prototype","Intl.RelativeTimeFormat.prototype")}}
+
允许向所有对象添加属性。
+
+ +

方法

+ +
+
{{jsxref("RelativeTimeFormat.supportedLocalesOf","Intl.RelativeTimeFormat.supportedLocalesOf()")}}
+
返回一个数组,其中包含所支持的语言环境,而不必回退到运行时的默认语言环境。
+
+ +

RelativeTimeFormat 实例

+ +

属性

+ +

RelativeTimeFormat 实例从其原型继承以下属性:

+ +

{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/RelativeTimeFormat/prototype','Properties')}}

+ +

方法

+ +

RelativeTimeFormat 实例从其原型继承以下方法:

+ +

{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/RelativeTimeFormat/prototype','Methods')}}

+ +

例子

+ +

基本format用法

+ +

以下示例显示如何使用英语创建相对时间格式化程序。

+ +
//在语言环境中创建相对时间格式化程序
+//显式传入默认值。
+const rtf = new Intl.RelativeTimeFormat("en",{
+    localeMatcher: "bestfit",//其他值:"lookup"
+    numeric: "always",//其他值:"auto"
+    style: "long",//其他值:"short"或"narrow"
+});
+
+//使用负值(-1)格式化相对时间。
+rtf.format(-1,"day");
+//>"1 day ago"
+
+//使用正值(1)格式化相对时间。
+rtf.format(1,"day");
+//>"in 1 day"
+ +

使用auto选项

+ +

如果numeric:auto选项被传递,它将生成字符串yesterdaytomorrow代替1 day agoin 1 day。这允许不必总是在输出中使用数值。

+ +
//在语言环境中创建相对时间格式化程序
+//使用数字:传入"auto"选项值。
+const rtf = new Intl.RelativeTimeFormat("en",{numeric: "auto"});
+
+//使用负值(-1)格式化相对时间。
+rtf.format(-1,"day");
+//>"yesterday"
+
+//使用正日单位(1)格式化相对时间。
+rtf.format(1,"day");
+//>"tomorrow"
+
+ +

运用 formatToParts

+ +

以下示例显示如何创建返回格式化部件的相对时间格式器

+ +
const rtf = new Intl.RelativeTimeFormat("en",{numeric: "auto"});
+
+//使用日期单位格式化相对时间。
+rtf.formatToParts(-1,"day");
+//> [{type: "literal",value: "yesterday"}]
+
+rtf.formatToParts(100,"day");
+//> [{type: "literal",value: "in"},
+//> {type: "integer",value: "100",unit: "day"},
+//> {type: "literal",value: "days"}]
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
Intl.RelativeTimeFormat ConstructorStage 3
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.Intl.RelativeTimeFormat")}}

+ +

See also

+ + +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/isfinite/index.html b/files/zh-cn/web/javascript/reference/global_objects/isfinite/index.html new file mode 100644 index 0000000000..b8f1c4d53c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/isfinite/index.html @@ -0,0 +1,107 @@ +--- +title: isFinite() +slug: Web/JavaScript/Reference/Global_Objects/isFinite +tags: + - JavaScript + - isFinite +translation_of: Web/JavaScript/Reference/Global_Objects/isFinite +--- +
{{jsSidebar("Objects")}}
+ +

该全局 isFinite() 函数用来判断被传入的参数值是否为一个有限数值(finite number)。在必要情况下,参数会首先转为一个数值。

+ +
{{EmbedInteractiveExample("pages/js/globalprops-isfinite.html")}}
+ +

语法

+ +
isFinite(testValue)
+ +

参数

+ +
+
testValue
+
用于检测有限性(finiteness)的值。
+
+ +

描述

+ +
+
isFinite 是全局的方法,不与任何对象有关系。
+
+ +

你可以用这个方法来判定一个数字是否是有限数字。isFinite 方法检测它参数的数值。如果参数是 NaN,正无穷大或者负无穷大,会返回false,其他返回 true

+ +

示例

+ +
isFinite(Infinity);  // false
+isFinite(NaN);       // false
+isFinite(-Infinity); // false
+
+isFinite(0);         // true
+isFinite(2e64);      // true, 在更强壮的Number.isFinite(null)中将会得到false
+
+
+isFinite("0");       // true, 在更强壮的Number.isFinite('0')中将会得到false
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.1.2.5', 'isFinite')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-isfinite-number', 'isFinite')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-isfinite-number', 'isFinite')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.isFinite")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/isnan/index.html b/files/zh-cn/web/javascript/reference/global_objects/isnan/index.html new file mode 100644 index 0000000000..e9fd9ff613 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/isnan/index.html @@ -0,0 +1,192 @@ +--- +title: isNaN() +slug: Web/JavaScript/Reference/Global_Objects/isNaN +tags: + - JavaScript + - Method + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/isNaN +--- +
{{jsSidebar("Objects")}}
+ +

isNaN() 函数用来确定一个值是否为{{jsxref("NaN")}} 。注:isNaN函数内包含一些非常有趣的规则;你也可以使用 ECMAScript 2015 中定义的 {{jsxref("Number.isNaN()")}} 来判断。

+ +

{{EmbedInteractiveExample("pages/js/globalprops-isnan.html")}}

+ +

语法

+ +
isNaN(value)
+ +

参数

+ +
+
value
+
要被检测的值。
+
+ +

返回值

+ +

如果给定值为 {{jsxref("NaN")}}则返回值为true;否则为false

+ +

描述

+ +

isNaN 函数的必要性

+ +

与 JavaScript 中其他的值不同,{{jsxref("Global_Objects/NaN", "NaN")}}不能通过相等操作符(== 和 ===)来判断 ,因为 NaN == NaNNaN === NaN 都会返回 false。 因此,isNaN 就很有必要了。

+ +

NaN值的产生

+ +

当算术运算返回一个未定义的或无法表示的值时,NaN就产生了。但是,NaN并不一定用于表示某些值超出表示范围的情况。将某些不能强制转换为数值的非数值转换为数值的时候,也会得到NaN

+ +

例如,0 除以0会返回NaN —— 但是其他数除以0则不会返回NaN

+ +

令人费解的怪异行为

+ +

如果isNaN函数的参数不是Number类型, isNaN函数会首先尝试将这个参数转换为数值,然后才会对转换后的结果是否是{{jsxref("NaN")}}进行判断。因此,对于能被强制转换为有效的非NaN数值来说(空字符串和布尔值分别会被强制转换为数值0和1),返回false值也许会让人感觉莫名其妙。比如说,空字符串就明显“不是数值(not a number)”。这种怪异行为起源于:"不是数值(not a number)"在基于IEEE-754数值的浮点计算体制中代表了一种特定的含义。isNaN函数其实等同于回答了这样一个问题:被测试的值在被强制转换成数值时会不会返回IEEE-754​中所谓的“不是数值(not a number)”。

+ +

下一个版本的ECMAScript (ES2015)包含{{jsxref("Number.isNaN()")}}函数。通过Number.isNaN(x)来检测变量x是否是一个NaN将会是一种可靠的做法。然而,在缺少Number.isNaN函数的情况下, 通过表达式(x != x) 来检测变量x是否是NaN会更加可靠。

+ +

一个isNaN的 polyfill 可以理解为(这个polyfill利用了NaN自身永不相等于自身这一特征 ):

+ +
var isNaN = function(value) {
+    var n = Number(value);
+    return n !== n;
+};
+ +

示例

+ +
isNaN(NaN);       // true
+isNaN(undefined); // true
+isNaN({});        // true
+
+isNaN(true);      // false
+isNaN(null);      // false
+isNaN(37);        // false
+
+// strings
+isNaN("37");      // false: 可以被转换成数值37
+isNaN("37.37");   // false: 可以被转换成数值37.37
+isNaN("37,5");    // true
+isNaN('123ABC');  // true:  parseInt("123ABC")的结果是 123, 但是Number("123ABC")结果是 NaN
+isNaN("");        // false: 空字符串被转换成0
+isNaN(" ");       // false: 包含空格的字符串被转换成0
+
+// dates
+isNaN(new Date());                // false
+isNaN(new Date().toString());     // true
+
+isNaN("blabla")   // true: "blabla"不能转换成数值
+                  // 转换成数值失败, 返回NaN
+
+ +

有用的特殊行为

+ +

有许多方式来看待isNaN():如果isNaN(x)返回false,那么x在任何算数表达式中都不会使表达式等于NaN;如果返回true,x会使所有算数表达式返回NaN。这就意味着,在JavaScript中,isNaN(x)==true等价于x-0=NaN(在JavaScript中 x-0 == NaN 总是返回false,所以你不用去测试它)。实际上, isNaN(x)isNaN(x - 0),isNaN(Number(x))Number.isNaN(x - 0),和Number.isNaN(Number(x)) 的返回值都是一样的 并且在JavaScript中isNaN(x)是这些表达式中最短的表达。

+ +

举个例子,可以利用这个特殊行为来检测函数的参数是可运算的(可以像number一样进行加减乘除等运算)。如果不可运算,则可赋予这个参数一个默认的值或其他合适的内容。这样,就可以得到一个隐式转换参数值的函数,而这得益于Javascript的全功能性。

+ +

例子

+ +
function increment(x) {
+  if (isNaN(x)) x = 0;
+  return x + 1;
+};
+
+// The same effect with Number.isNaN():
+function increment(x) {
+  if (Number.isNaN(Number(x))) x = 0;
+  return x + 1;
+};
+
+// In the following cases for the function's argument x,
+// isNaN(x) is always false, although x is indeed not a
+// number, but can be used as such in arithmetical
+// expressions
+increment("");            // 1: "" is converted to 0
+increment(new String());  // 1: String object representing an empty string is converted to 0
+increment([]);            // 1: [] is converted to 0
+increment(new Array());   // 1: Array object representing an empty array is converted to 0
+increment("0");           // 1: "0" is converted to 0
+increment("1");           // 2: "1" is converted to 1
+increment("0.1");         // 1.1: "0.1" is converted to 0.1
+increment("Infinity");    // Infinity: "Infinity" is converted to Infinity
+increment(null);          // 1: null is converted to 0
+increment(false);         // 1: false is converted to 0
+increment(true);          // 2: true is converted to 1
+increment(new Date());    // returns current date/time in milliseconds plus 1
+
+// In the following cases for the function's argument x,
+// isNaN(x) is always false and x is indeed a number
+increment(-1);            // 0
+increment(-0.1);          // 0.9
+increment(0);             // 1
+increment(1);             // 2
+increment(2);             // 3
+// ... and so on ...
+increment(Infinity);      // Infinity
+
+// In the following cases for the function's argument x,
+// isNaN(x) is always true and x is really not a number,
+// thus the function replaces it by 0 and returns 1
+increment(String);            // 1
+increment(Array);             // 1
+increment("blabla");          // 1
+increment("-blabla");         // 1
+increment(0/0);               // 1
+increment("0/0");             // 1
+increment(Infinity/Infinity); // 1
+increment(NaN);               // 1
+increment(undefined);         // 1
+increment();                  // 1
+
+// isNaN(x) is always the same as isNaN(Number(x)),
+// but the presence of x is mandatory here!
+isNaN(x) == isNaN(Number(x))  // true for every value of x, including x == undefined,
+                              // because isNaN(undefined) == true and Number(undefined) returns NaN,
+                              // but ...
+isNaN() == isNaN(Number())    // false, because isNaN() == true and Number() == 0
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.1.2.4', 'isNaN')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-isnan-number', 'isNaN')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-isnan-number', 'isNaN')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.isNaN")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/iterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/iterator/index.html new file mode 100644 index 0000000000..775c8d60d6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/iterator/index.html @@ -0,0 +1,188 @@ +--- +title: Iterator +slug: Web/JavaScript/Reference/Global_Objects/Iterator +tags: + - Deprecated +translation_of: Archive/Web/Iterator +--- +
{{jsSidebar("Objects")}}
+ +
非标准。 Iterator 函数是一个 SpiderMonkey 专有特性,并且会在某一时刻被删除。为将来使用的话,请考虑使用 {{jsxref("Statements/for...of", "for...of")}} 循环和  迭代协议
+ +

Iterator 函数返回一个对象,它实现了遗留的迭代协议,并且迭代了一个对象的可枚举属性。

+ +

语法

+ +
Iterator(object, [keyOnly])
+ +

参数

+ +
+
object
+
要迭代属性的对象。
+
keyOnly
+
 如果keyOnly是真值,Iterator.prototype.next 只返回property_name
+
+ +

描述

+ +

返回迭代了object的Iterator 实例。如果keyOnly为假值,则Iterator 实例返回每次迭代而生成的 [property_name, property_value] 数组,否则,如果keyOnly是真值,则它返回每次迭代的 property_name。如果objectIterator 实例或 {{jsxref("Generator")}} 实例 ,则它返回 object 自身。

+ +

属性

+ +
+
Iterator.prototype[@@iterator]
+
返回一个函数,它返回符合{{jsxref("Iteration_protocols", "迭代协议", "", 1)}}的迭代对象。
+
+ +

方法

+ +
+
Iterator.prototype.next
+
返回[property_name, property_value] 格式或property_name 的下一项。 如果没有更多项,抛出 StopIteration
+
+ +

示例

+ +

迭代一个对象的属性

+ +
var a = {
+  x: 10,
+  y: 20,
+};
+var iter = Iterator(a);
+console.log(iter.next()); // ["x", 10]
+console.log(iter.next()); // ["y", 20]
+console.log(iter.next()); // throws StopIteration
+
+ +

使用遗留的解构for-in迭代对象的属性

+ +
var a = {
+  x: 10,
+  y: 20,
+};
+
+for (var [name, value] in Iterator(a)) {
+  console.log(name, value);   // x 10
+                              // y 20
+}
+
+ +

使用for-of迭代

+ +
var a = {
+  x: 10,
+  y: 20,
+};
+
+for (var [name, value] of Iterator(a)) {  // @@iterator is used
+  console.log(name, value);   // x 10
+                              // y 20
+}
+
+ +

迭代属性名

+ +
var a = {
+  x: 10,
+  y: 20,
+};
+
+for (var name in Iterator(a, true)) {
+  console.log(name);   // x
+                       // y
+}
+
+ +

传入 Generator 实例

+ +
function* f() {
+  yield 'a';
+  yield 'b';
+}
+var g = f();
+
+console.log(g == Iterator(g)); // true
+
+for (var v in Iterator(g)) {
+  console.log(v);   // a
+                    // b
+}
+
+ +

传入 Iterator 实例

+ +
var a = {
+  x: 10,
+  y: 20,
+};
+
+var i = Iterator(a);
+
+console.log(i == Iterator(i)); // true
+
+ +

规范

+ +

非标准。不是目前任何标准文档的一部分。

+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/json/index.html b/files/zh-cn/web/javascript/reference/global_objects/json/index.html new file mode 100644 index 0000000000..98b734c78d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/json/index.html @@ -0,0 +1,203 @@ +--- +title: JSON +slug: Web/JavaScript/Reference/Global_Objects/JSON +tags: + - JSON + - JavaScript + - Object + - Reference + - polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/JSON +--- +
{{JSRef}}
+ +

JSON对象包含两个方法: 用于解析 JavaScript Object Notation  ({{glossary("JSON")}}) 的 parse() 方法,以及将对象/值转换为 JSON字符串的 stringify() 方法。除了这两个方法, JSON这个对象本身并没有其他作用,也不能被调用或者作为构造函数调用。

+ +

描述

+ +

JavaScript Object Notation

+ +

JSON 是一种语法,用来序列化对象、数组、数值、字符串、布尔值和 {{jsxref("null")}} 。它基于 JavaScript 语法,但与之不同:JavaScript不是JSON,JSON也不是JavaScript参考 JSON:并不是JavaScript 的子集

+ + + + + + + + + + + + + + + + + + + + + + + +
JavaScript 与 JSON 的区别
JavaScript类型JSON 的不同点
对象和数组 +

属性名称必须是双引号括起来的字符串;最后一个属性后不能有逗号。

+
数值禁止出现前导零( JSON.stringify 方法自动忽略前导零,而在 JSON.parse 方法中将会抛出 SyntaxError);如果有小数点, 则后面至少跟着一位数字。
字符串 +

只有有限的一些字符可能会被转义;禁止某些控制字符; Unicode 行分隔符 (U+2028)和段分隔符 (U+2029)被允许 ; 字符串必须用双引号括起来。请参考下面的示例,可以看到 {{jsxref("JSON.parse()")}} 能够正常解析,但将其当作JavaScript解析时会抛出 {{jsxref("SyntaxError")}} 错误:

+ +
+let code = '"\u2028\u2029"';
+JSON.parse(code);  // 正常
+eval(code);  // 错误
+
+
+ +

完整的JSON语法定义如下:

+ +
JSON = null
+    or true or false
+    or JSONNumber
+    or JSONString
+    or JSONObject
+    or JSONArray
+
+JSONNumber = - PositiveNumber
+          or PositiveNumber
+PositiveNumber = DecimalNumber
+              or DecimalNumber . Digits
+              or DecimalNumber . Digits ExponentPart
+              or DecimalNumber ExponentPart
+DecimalNumber = 0
+             or OneToNine Digits
+ExponentPart = e Exponent
+            or E Exponent
+Exponent = Digits
+        or + Digits
+        or - Digits
+Digits = Digit
+      or Digits Digit
+Digit = 0 through 9
+OneToNine = 1 through 9
+
+JSONString = ""
+          or " StringCharacters "
+StringCharacters = StringCharacter
+                or StringCharacters StringCharacter
+StringCharacter = any character
+                  except " or \ or U+0000 through U+001F
+               or EscapeSequence
+EscapeSequence = \" or \/ or \\ or \b or \f or \n or \r or \t
+              or \u HexDigit HexDigit HexDigit HexDigit
+HexDigit = 0 through 9
+        or A through F
+        or a through f
+
+JSONObject = { }
+          or { Members }
+Members = JSONString : JSON
+       or Members , JSONString : JSON
+
+JSONArray = [ ]
+         or [ ArrayElements ]
+ArrayElements = JSON
+             or ArrayElements , JSON
+
+ +

JSONNumber(数字内部不允许包含空格)或JSONString(字符串内部的空格被解释为相应的字符,否则就有问题了)之外的任何位置可以有多余的空白字符。JSON只支持这些空白字符: 制表符(U+0009),回车(U+000D),换行(U+000A)以及空格(U+0020)。

+ +

方法

+ +
+
{{jsxref("JSON.parse()")}}
+
解析JSON字符串并返回对应的值,可以额外传入一个转换函数,用来将生成的值和其属性, 在返回之前进行某些修改。
+
{{jsxref("JSON.stringify()")}}
+
返回与指定值对应的JSON字符串,可以通过额外的参数, 控制仅包含某些属性, 或者以自定义方法来替换某些key对应的属性值。
+
+ +

Polyfill

+ +

JSON对象可能不被老版本的浏览器支持。可以将下面的代码放到JS脚本最开始的位置,这样就可以在没有原生支持 JSON 对象的浏览器(如IE6)中使用 JSON对象。

+ +

以下算法是对原生JSON对象的模仿:

+ +
if (!window.JSON) {
+  window.JSON = {
+    parse: function(sJSON) { return eval('(' + sJSON + ')'); },
+    stringify: (function () {
+      var toString = Object.prototype.toString;
+      var isArray = Array.isArray || function (a) { return toString.call(a) === '[object Array]'; };
+      var escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'};
+      var escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); };
+      var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g;
+      return function stringify(value) {
+        if (value == null) {
+          return 'null';
+        } else if (typeof value === 'number') {
+          return isFinite(value) ? value.toString() : 'null';
+        } else if (typeof value === 'boolean') {
+          return value.toString();
+        } else if (typeof value === 'object') {
+          if (typeof value.toJSON === 'function') {
+            return stringify(value.toJSON());
+          } else if (isArray(value)) {
+            var res = '[';
+            for (var i = 0; i < value.length; i++)
+              res += (i ? ', ' : '') + stringify(value[i]);
+            return res + ']';
+          } else if (toString.call(value) === '[object Object]') {
+            var tmp = [];
+            for (var k in value) {
+              if (value.hasOwnProperty(k))
+                tmp.push(stringify(k) + ': ' + stringify(value[k]));
+            }
+            return '{' + tmp.join(', ') + '}';
+          }
+        }
+        return '"' + value.toString().replace(escRE, escFunc) + '"';
+      };
+    })()
+  };
+}
+
+ +

业界更专业, 更强大的JSON对象 polyfills 是 JSON2 和 JSON3

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES5.1', '#sec-15.12', 'JSON')}}{{Spec2('ES5.1')}}Initial definition.
{{SpecName('ES6', '#sec-json-object', 'JSON')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-json-object', 'JSON')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.JSON")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/json/parse/index.html b/files/zh-cn/web/javascript/reference/global_objects/json/parse/index.html new file mode 100644 index 0000000000..e1e970a1e4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/json/parse/index.html @@ -0,0 +1,224 @@ +--- +title: JSON.parse() +slug: Web/JavaScript/Reference/Global_Objects/JSON/parse +tags: + - ECMAScript 5 + - JSON + - JavaScript + - 参考 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/JSON/parse +--- +
{{JSRef}}
+ +

JSON.parse() 方法用来解析JSON字符串,构造由字符串描述的JavaScript值或对象。提供可选的 reviver 函数用以在返回之前对所得到的对象执行变换(操作)。

+ +
{{EmbedInteractiveExample("pages/js/json-parse.html")}}
+ + + +

语法

+ +
JSON.parse(text[, reviver])
+ +

参数

+ +
+
text
+
要被解析成 JavaScript 值的字符串,关于JSON的语法格式,请参考:{{jsxref("JSON")}}。
+
reviver {{optional_inline()}}
+
转换器, 如果传入该参数(函数),可以用来修改解析生成的原始值,调用时机在 parse 函数返回之前。
+
+ +

返回值

+ +

{{jsxref("Object")}} 类型, 对应给定 JSON 文本的对象/值。

+ +

异常

+ +

若传入的字符串不符合 JSON 规范,则会抛出 {{jsxref("SyntaxError")}} 异常。

+ +

示例

+ +

使用 JSON.parse()

+ +
JSON.parse('{}');              // {}
+JSON.parse('true');            // true
+JSON.parse('"foo"');           // "foo"
+JSON.parse('[1, 5, "false"]'); // [1, 5, "false"]
+JSON.parse('null');            // null
+
+ +

使用 reviver 函数

+ +

如果指定了 reviver 函数,则解析出的 JavaScript 值(解析值)会经过一次转换后才将被最终返回(返回值)。更具体点讲就是:解析值本身以及它所包含的所有属性,会按照一定的顺序(从最最里层的属性开始,一级级往外,最终到达顶层,也就是解析值本身)分别的去调用 reviver 函数,在调用过程中,当前属性所属的对象会作为 this 值,当前属性名和属性值会分别作为第一个和第二个参数传入 reviver 中。如果 reviver 返回 undefined,则当前属性会从所属对象中删除,如果返回了其他值,则返回的值会成为当前属性新的属性值。

+ +

当遍历到最顶层的值(解析值)时,传入 reviver 函数的参数会是空字符串 ""(因为此时已经没有真正的属性)和当前的解析值(有可能已经被修改过了),当前的 this 值会是 {"": 修改过的解析值},在编写 reviver 函数时,要注意到这个特例。(这个函数的遍历顺序依照:从最内层开始,按照层级顺序,依次向外遍历)

+ +
JSON.parse('{"p": 5}', function (k, v) {
+    if(k === '') return v;     // 如果到了最顶层,则直接返回属性值,
+    return v * 2;              // 否则将属性值变为原来的 2 倍。
+});                            // { p: 10 }
+
+JSON.parse('{"1": 1, "2": 2,"3": {"4": 4, "5": {"6": 6}}}', function (k, v) {
+    console.log(k); // 输出当前的属性名,从而得知遍历顺序是从内向外的,
+                    // 最后一个属性名会是个空字符串。
+    return v;       // 返回原始属性值,相当于没有传递 reviver 参数。
+});
+
+// 1
+// 2
+// 4
+// 6
+// 5
+// 3
+// ""
+
+ +

JSON.parse() 不允许用逗号作为结尾

+ +
// both will throw a SyntaxError
+JSON.parse("[1, 2, 3, 4, ]");
+JSON.parse('{"foo" : 1, }');
+
+ +

Polyfill

+ +
// From https://github.com/douglascrockford/JSON-js/blob/master/json2.js
+if (typeof JSON.parse !== "function") {
+    var rx_one = /^[\],:{}\s]*$/;
+    var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
+    var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
+    var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
+    var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+    JSON.parse = function(text, reviver) {
+
+        // The parse method takes a text and an optional reviver function, and returns
+        // a JavaScript value if the text is a valid JSON text.
+
+        var j;
+
+        function walk(holder, key) {
+
+            // The walk method is used to recursively walk the resulting structure so
+            // that modifications can be made.
+
+            var k;
+            var v;
+            var value = holder[key];
+            if (value && typeof value === "object") {
+                for (k in value) {
+                    if (Object.prototype.hasOwnProperty.call(value, k)) {
+                        v = walk(value, k);
+                        if (v !== undefined) {
+                            value[k] = v;
+                        } else {
+                            delete value[k];
+                        }
+                    }
+                }
+            }
+            return reviver.call(holder, key, value);
+        }
+
+
+        // Parsing happens in four stages. In the first stage, we replace certain
+        // Unicode characters with escape sequences. JavaScript handles many characters
+        // incorrectly, either silently deleting them, or treating them as line endings.
+
+        text = String(text);
+        rx_dangerous.lastIndex = 0;
+        if (rx_dangerous.test(text)) {
+            text = text.replace(rx_dangerous, function(a) {
+                return (
+                    "\\u" +
+                    ("0000" + a.charCodeAt(0).toString(16)).slice(-4)
+                );
+            });
+        }
+
+        // In the second stage, we run the text against regular expressions that look
+        // for non-JSON patterns. We are especially concerned with "()" and "new"
+        // because they can cause invocation, and "=" because it can cause mutation.
+        // But just to be safe, we want to reject all unexpected forms.
+
+        // We split the second stage into 4 regexp operations in order to work around
+        // crippling inefficiencies in IE's and Safari's regexp engines. First we
+        // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
+        // replace all simple value tokens with "]" characters. Third, we delete all
+        // open brackets that follow a colon or comma or that begin the text. Finally,
+        // we look to see that the remaining characters are only whitespace or "]" or
+        // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
+
+        if (
+            rx_one.test(
+                text
+                .replace(rx_two, "@")
+                .replace(rx_three, "]")
+                .replace(rx_four, "")
+            )
+        ) {
+
+            // In the third stage we use the eval function to compile the text into a
+            // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
+            // in JavaScript: it can begin a block or an object literal. We wrap the text
+            // in parens to eliminate the ambiguity.
+
+            j = eval("(" + text + ")");
+
+            // In the optional fourth stage, we recursively walk the new structure, passing
+            // each name/value pair to a reviver function for possible transformation.
+
+            return (typeof reviver === "function") ?
+                walk({
+                    "": j
+                }, "") :
+                j;
+        }
+
+        // If the text is not JSON parseable, then a SyntaxError is thrown.
+
+        throw new SyntaxError("JSON.parse");
+    };
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES5.1', '#sec-15.12.2', 'JSON.parse')}}{{Spec2('ES5.1')}}首次定义,于 JavaScript 1.7 版本中实现。
{{SpecName('ES6', '#sec-json.parse', 'JSON.parse')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-json.parse', 'JSON.parse')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.JSON.parse")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/json/stringify/index.html b/files/zh-cn/web/javascript/reference/global_objects/json/stringify/index.html new file mode 100644 index 0000000000..3ccfd067d3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/json/stringify/index.html @@ -0,0 +1,267 @@ +--- +title: JSON.stringify() +slug: Web/JavaScript/Reference/Global_Objects/JSON/stringify +tags: + - JSON + - JSON.stringify() + - JavaScript + - Method + - Reference + - stringify + - 字符串 +translation_of: Web/JavaScript/Reference/Global_Objects/JSON/stringify +--- +
{{JSRef}}
+ +

JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串,如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性。

+ +

{{EmbedInteractiveExample("pages/js/json-stringify.html")}}

+ +

语法

+ +
JSON.stringify(value[, replacer [, space]])
+
+ +

参数

+ +
+
value
+
将要序列化成 一个 JSON 字符串的值。
+
replacer {{optional_inline}}
+
如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。
+
space {{optional_inline}}
+
指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为10。该值若小于1,则意味着没有空格;如果该参数为字符串(当字符串长度超过10个字母,取其前10个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。
+
+

返回值

+
+
一个表示给定值的JSON字符串。
+
+ +

异常

+ + + +

描述

+ +

JSON.stringify()将值转换为相应的JSON格式:

+ + + +

示例

+ +

使用 JSON.stringify

+ +
JSON.stringify({});                        // '{}'
+JSON.stringify(true);                      // 'true'
+JSON.stringify("foo");                     // '"foo"'
+JSON.stringify([1, "false", false]);       // '[1,"false",false]'
+JSON.stringify({ x: 5 });                  // '{"x":5}'
+
+JSON.stringify({x: 5, y: 6});
+// "{"x":5,"y":6}"
+
+JSON.stringify([new Number(1), new String("false"), new Boolean(false)]);
+// '[1,"false",false]'
+
+JSON.stringify({x: undefined, y: Object, z: Symbol("")});
+// '{}'
+
+JSON.stringify([undefined, Object, Symbol("")]);
+// '[null,null,null]'
+
+JSON.stringify({[Symbol("foo")]: "foo"});
+// '{}'
+
+JSON.stringify({[Symbol.for("foo")]: "foo"}, [Symbol.for("foo")]);
+// '{}'
+
+JSON.stringify(
+    {[Symbol.for("foo")]: "foo"},
+    function (k, v) {
+        if (typeof k === "symbol"){
+            return "a symbol";
+        }
+    }
+);
+
+
+// undefined
+
+// 不可枚举的属性默认会被忽略:
+JSON.stringify(
+    Object.create(
+        null,
+        {
+            x: { value: 'x', enumerable: false },
+            y: { value: 'y', enumerable: true }
+        }
+    )
+);
+
+// "{"y":"y"}"
+
+ +

replacer参数

+ +

replacer 参数可以是一个函数或者一个数组。作为函数,它有两个参数,键(key)和值(value),它们都会被序列化。

+ +

在开始时, replacer 函数会被传入一个空字符串作为 key 值,代表着要被 stringify 的这个对象。随后每个对象或数组上的属性会被依次传入。 

+ +

函数应当返回JSON字符串中的value, 如下所示:

+ + + +

注意: 不能用 replacer 方法,从数组中移除值(values),如若返回 undefined 或者一个函数,将会被 null 取代。

+ +

例子(function)

+ +
function replacer(key, value) {
+  if (typeof value === "string") {
+    return undefined;
+  }
+  return value;
+}
+
+var foo = {foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7};
+var jsonString = JSON.stringify(foo, replacer);
+ +

JSON序列化结果为 {"week":45,"month":7}.

+ +

例子(array)

+ +

如果 replacer 是一个数组,数组的值代表将被序列化成 JSON 字符串的属性名。

+ +
JSON.stringify(foo, ['week', 'month']);
+// '{"week":45,"month":7}', 只保留 “week” 和 “month” 属性值。
+ +

space 参数

+ +

space 参数用来控制结果字符串里面的间距。如果是一个数字, 则在字符串化时每一级别会比上一级别缩进多这个数字值的空格(最多10个空格);如果是一个字符串,则每一级别会比上一级别多缩进该字符串(或该字符串的前10个字符)。

+ +
JSON.stringify({ a: 2 }, null, " ");   // '{\n "a": 2\n}'
+ +

使用制表符(\t)来缩进:

+ +
JSON.stringify({ uno: 1, dos : 2 }, null, '\t')
+// '{            \
+//     "uno": 1, \
+//     "dos": 2  \
+// }'
+
+ +

toJSON 方法

+ +

如果一个被序列化的对象拥有 toJSON 方法,那么该 toJSON 方法就会覆盖该对象默认的序列化行为:不是该对象被序列化,而是调用 toJSON 方法后的返回值会被序列化,例如:

+ +
var obj = {
+  foo: 'foo',
+  toJSON: function () {
+    return 'bar';
+  }
+};
+JSON.stringify(obj);      // '"bar"'
+JSON.stringify({x: obj}); // '{"x":"bar"}'
+
+ +

JSON.stringify用作 JavaScript

+ +

注意 JSON 不是 JavaScript 严格意义上的子集,在 JSON 中不需要省略两条终线(Line separator 和 Paragraph separator),但在 JavaScript 中需要被省略。因此,如果 JSON 被用作 JSONP 时,下面方法可以使用:

+ +
function jsFriendlyJSONStringify (s) {
+    return JSON.stringify(s).
+        replace(/\u2028/g, '\\u2028').
+        replace(/\u2029/g, '\\u2029');
+}
+
+var s = {
+    a: String.fromCharCode(0x2028),
+    b: String.fromCharCode(0x2029)
+};
+try {
+    eval('(' + JSON.stringify(s) + ')');
+} catch (e) {
+    console.log(e); // "SyntaxError: unterminated string literal"
+}
+
+// No need for a catch
+eval('(' + jsFriendlyJSONStringify(s) + ')');
+
+// console.log in Firefox unescapes the Unicode if
+//   logged to console, so we use alert
+alert(jsFriendlyJSONStringify(s)); // {"a":"\u2028","b":"\u2029"}
+ +

使用 JSON.stringify 结合 localStorage 的例子

+ +

一些时候,你想存储用户创建的一个对象,并且,即使在浏览器被关闭后仍能恢复该对象。下面的例子是 JSON.stringify 适用于这种情形的一个样板:

+ +
// 创建一个示例数据
+var session = {
+    'screens' : [],
+    'state' : true
+};
+session.screens.push({"name":"screenA", "width":450, "height":250});
+session.screens.push({"name":"screenB", "width":650, "height":350});
+session.screens.push({"name":"screenC", "width":750, "height":120});
+session.screens.push({"name":"screenD", "width":250, "height":60});
+session.screens.push({"name":"screenE", "width":390, "height":120});
+session.screens.push({"name":"screenF", "width":1240, "height":650});
+
+// 使用 JSON.stringify 转换为 JSON 字符串
+// 然后使用 localStorage 保存在 session 名称里
+localStorage.setItem('session', JSON.stringify(session));
+
+// 然后是如何转换通过 JSON.stringify 生成的字符串,该字符串以 JSON 格式保存在 localStorage 里
+var restoredSession = JSON.parse(localStorage.getItem('session'));
+
+// 现在 restoredSession 包含了保存在 localStorage 里的对象
+console.log(restoredSession);
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范名称及链接规范状态
{{SpecName('ES5.1', '#sec-15.12.3', 'JSON.stringify')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-json.stringify', 'JSON.stringify')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.JSON.stringify")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/@@iterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/@@iterator/index.html new file mode 100644 index 0000000000..aa4c789a26 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/@@iterator/index.html @@ -0,0 +1,101 @@ +--- +title: 'Map.prototype[@@iterator]()' +slug: Web/JavaScript/Reference/Global_Objects/Map/@@iterator +tags: + - ECMAScript 2015 + - Iterator + - JavaScript + - Map + - Method + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Map/@@iterator +--- +
{{JSRef}}
+ +

@@iterator 属性的初始值与 {{jsxref("Map.prototype.entries()", "entries")}} 属性的初始值是同一个函数对象。

+ +
{{EmbedInteractiveExample("pages/js/map-prototype-@@iterator.html")}}
+ + + +

语法

+ +
myMap[Symbol.iterator]
+ +

返回值

+ +

map 的 iterator 函数默认就是 {{jsxref("Map.prototype.entries()", "entries()")}} 函数。

+ +

示例

+ +

使用 [@@iterator]()

+ +
var myMap = new Map();
+myMap.set('0', 'foo');
+myMap.set(1, 'bar');
+myMap.set({}, 'baz');
+
+var mapIter = myMap[Symbol.iterator]();
+//返回的其实是个generator
+console.log(mapIter.next().value); // ["0", "foo"]
+console.log(mapIter.next().value); // [1, "bar"]
+console.log(mapIter.next().value); // [Object, "baz"]
+
+ +

for..of中使用[@@iterator]() 

+ +
var myMap = new Map();
+myMap.set('0', 'foo');
+myMap.set(1, 'bar');
+myMap.set({}, 'baz');
+
+for (const entry of myMap) {
+  console.log(entry);
+}
+// ["0", "foo"]
+// [1, "bar"]
+// [{}, "baz"]
+
+for (var v of myMap) {
+  console.log(v);
+}
+
+// 0: foo
+// 1: bar
+// [Object]: baz
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-map.prototype-@@iterator', 'Map.prototype[@@iterator]()')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype-@@iterator', 'Map.prototype[@@iterator]()')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Map.@@iterator")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/@@species/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/@@species/index.html new file mode 100644 index 0000000000..ded2acd30b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/@@species/index.html @@ -0,0 +1,67 @@ +--- +title: 'get Map[@@species]' +slug: Web/JavaScript/Reference/Global_Objects/Map/@@species +translation_of: Web/JavaScript/Reference/Global_Objects/Map/@@species +--- +
{{JSRef}}
+ +

 Map[@@species] 访问器属性会返回一个 Map 构造函数.

+ +

语法

+ +
Map[Symbol.species]
+
+ +

描述

+ +

The species accessor property returns the default constructor for Map objects. Subclass constructors may over-ride it to change the constructor assignment.

+ +

案例

+ +

The species property returns the default constructor function, which is the Map constructor for Map objects:

+ +
Map[Symbol.species]; // function Map()
+ +

In a derived collection object (e.g. your custom map MyMap), the MyMap species is the MyMap constructor. However, you might want to overwrite this, in order to return parent Map objects in your derived class methods:

+ +
class MyMap extends Map {
+  // 重写覆盖 MyMap species to the parent Map constructor
+  static get [Symbol.species]() { return Map; }
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-get-map-@@species', 'get Map [ @@species ]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-get-map-@@species', 'get Map [ @@species ]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Map.@@species")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/@@tostringtag/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/@@tostringtag/index.html new file mode 100644 index 0000000000..c6a1e3c81b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/@@tostringtag/index.html @@ -0,0 +1,95 @@ +--- +title: 'Map.prototype[@@toStringTag]' +slug: Web/JavaScript/Reference/Global_Objects/Map/@@toStringTag +translation_of: Web/JavaScript/Reference/Global_Objects/Map/@@toStringTag +--- +
{{JSRef}}
+ +

 Map[@@toStringTag] 的初始值是"Map".

+ +
{{js_property_attributes(0,0,1)}}
+ +

语法

+ +
Map[Symbol.toStringTag]
+ +

示例

+ +
Object.prototype.toString.call(new Map()) // "[object Map]"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-map.prototype-@@tostringtag', 'Map.prototype[@@toStringTag]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype-@@tostringtag', 'Map.prototype[@@toStringTag]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +

{{CompatibilityTable}} 

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatChrome(44.0) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{ CompatNo }}{{ CompatChrome(44.0) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatChrome(44.0)}}
+
diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/clear/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/clear/index.html new file mode 100644 index 0000000000..8244d179c2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/clear/index.html @@ -0,0 +1,76 @@ +--- +title: Map.prototype.clear() +slug: Web/JavaScript/Reference/Global_Objects/Map/clear +tags: + - ECMAScript 2015 + - JavaScript + - Map +translation_of: Web/JavaScript/Reference/Global_Objects/Map/clear +--- +
{{JSRef}}
+ +

clear()方法会移除Map对象中的所有元素。

+ +
{{EmbedInteractiveExample("pages/js/map-prototype-clear.html")}}
+ + + +

语法

+ +
myMap.clear();
+
+ +

返回值

+ +

{{jsxref("undefined")}}.

+ +

示例

+ +

调用clear方法

+ +
var myMap = new Map();
+myMap.set("bar", "baz");
+myMap.set(1, "foo");
+
+myMap.size;       // 2
+myMap.has("bar"); // true
+
+myMap.clear();
+
+myMap.size;       // 0
+myMap.has("bar")  // false
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-map.prototype.clear', 'Map.prototype.clear')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype.clear', 'Map.prototype.clear')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Map.clear")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/delete/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/delete/index.html new file mode 100644 index 0000000000..4b8fb98c3f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/delete/index.html @@ -0,0 +1,83 @@ +--- +title: Map.prototype.delete() +slug: Web/JavaScript/Reference/Global_Objects/Map/delete +tags: + - ECMAScript 2015 + - JavaScript + - Map + - Method + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Map/delete +--- +
{{JSRef}}
+ +

 delete() 方法用于移除 Map 对象中指定的元素。

+ +
{{EmbedInteractiveExample("pages/js/map-prototype-delete.html")}}
+ + + +

语法

+ +
myMap.delete(key);
+ +

参数

+ +
+
key
+
必须。从 Map 对象中移除的元素的键。
+
+ +

返回值

+ +
+
Boolean
+
如果 Map 对象中存在该元素,则移除它并返回 true;否则如果该元素不存在则返回 false
+
+ +

示例

+ +

使用 delete 方法

+ +
var myMap = new Map();
+myMap.set("bar", "foo");
+
+myMap.delete("bar"); // 返回 true。成功地移除元素
+myMap.has("bar");    // 返回 false。"bar" 元素将不再存在于 Map 实例中
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-map.prototype.delete', 'Map.prototype.delete')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype.delete', 'Map.prototype.delete')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Map.delete")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/entries/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/entries/index.html new file mode 100644 index 0000000000..f97881755e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/entries/index.html @@ -0,0 +1,72 @@ +--- +title: Map.prototype.entries() +slug: Web/JavaScript/Reference/Global_Objects/Map/entries +tags: + - Map +translation_of: Web/JavaScript/Reference/Global_Objects/Map/entries +--- +
{{JSRef}}
+ +

entries() 方法返回一个新的包含 [key, value] 对的 Iterator 对象,返回的迭代器的迭代顺序与 Map 对象的插入顺序相同。

+ +

{{EmbedInteractiveExample("pages/js/map-prototype-entries.html")}}

+ +

语法

+ +
myMap.entries()
+
+ +

返回值

+ +

一个新的 {{jsxref("Map")}} 迭代器对象.

+ +

示例

+ +

entries()的使用

+ +
var myMap = new Map();
+myMap.set("0", "foo");
+myMap.set(1, "bar");
+myMap.set({}, "baz");
+
+var mapIter = myMap.entries();
+
+console.log(mapIter.next().value); // ["0", "foo"]
+console.log(mapIter.next().value); // [1, "bar"]
+console.log(mapIter.next().value); // [Object, "baz"]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-map.prototype.entries', 'Map.prototype.entries')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-map.prototype.entries', 'Map.prototype.entries')}}{{Spec2('ES2015')}}Initial definition.
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Map.entries")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/foreach/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/foreach/index.html new file mode 100644 index 0000000000..f6540d7412 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/foreach/index.html @@ -0,0 +1,109 @@ +--- +title: Map.prototype.forEach() +slug: Web/JavaScript/Reference/Global_Objects/Map/forEach +tags: + - ECMAScript 2015 + - JavaScript + - Map + - Method + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Map/forEach +--- +
{{JSRef}}
+ +

forEach() 方法按照插入顺序依次对 Map 中每个键/值对执行一次给定的函数

+ +
{{EmbedInteractiveExample("pages/js/map-prototype-foreach.html")}}
+ + + +

语法

+ +
myMap.forEach(callback([value][,key][,map])[, thisArg])
+ +

参数

+ +
+
callback
+
+

myMap 中每个元素所要执行的函数。它具有如下的参数

+ +
+
value {{Optional_Inline}}
+
每个迭代的值。
+
key {{Optional_Inline}}
+
每个迭代的键。
+
map {{Optional_Inline}}
+
被迭代的map(上文语法框中的 myMap)。
+
+
+
thisArg {{Optional_Inline}}
+
callback 执行中使用的 this 的值。
+
+ +

返回值

+ +

{{jsxref("undefined")}}.

+ +

描述

+ +

forEach 方法会对map中每个真实存在的键执行一次给定的 callback 函数。它不会对被删除的键执行函数。然而,它会对每个值为 undefined 的键执行函数。

+ +

callback 接收三个参数

+ + + +

如果 forEach 中含有 thisArg 参数,那么每次 callback 被调用时,都会被用作 this 的值。否则,undefined 将会被用作 this 的值。按照函数观察到 this 的常用规则callback 函数最终可观察到 this 值。

+ +

每个值只被访问一次,除非它被删除了或者在 forEach 结束前被改变了。callback 不会对在被访问前就删除的元素执行。在 forEach 结束前被添加的元素将会被访问。

+ +

forEach 会对 Map 对象中的每个元素执行一次 callback。它不会返回值。

+ +

示例

+ +

输出一个 Map 对象中的内容

+ +

以下的代码在每行中打印一个 Map 对象中的元素

+ +
function logMapElements(value, key, map) {
+    console.log(`map.get('${key}') = ${value}`)
+}
+new Map([['foo', 3], ['bar', {}], ['baz', undefined]]).forEach(logMapElements)
+// logs:
+// "map.get('foo') = 3"
+// "map.get('bar') = [object Object]"
+// "map.get('baz') = undefined"
+
+ +

规范

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-map.prototype.foreach', 'Map.prototype.forEach')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Map.forEach")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/get/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/get/index.html new file mode 100644 index 0000000000..1de9947bc4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/get/index.html @@ -0,0 +1,81 @@ +--- +title: Map.prototype.get() +slug: Web/JavaScript/Reference/Global_Objects/Map/get +tags: + - ECMAScript 2015 + - JavaScript + - Map + - Method + - Prototype + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Map/get +--- +
{{JSRef}}
+ +

get() 方法返回某个 Map 对象中的一个指定元素。

+ +
{{EmbedInteractiveExample("pages/js/map-prototype-get.html")}}
+ + + +

语法

+ +
myMap.get(key);
+ +

参数

+ +
+
key
+
必须参数,也是它唯一的参数,要从目标 Map 对象中获取的元素的键。
+
+ +

返回值

+ +

返回一个 Map 对象中与指定键相关联的值,如果找不到这个键则返回 undefined

+ +

示例

+ +

使用 get 方法

+ +
var myMap = new Map();
+myMap.set("bar", "foo");
+
+myMap.get("bar");  // 返回 "foo"
+myMap.get("baz");  // 返回 undefined
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-map.prototype.get', 'Map.prototype.get')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype.get', 'Map.prototype.get')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Map.get")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/has/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/has/index.html new file mode 100644 index 0000000000..73eb4550d0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/has/index.html @@ -0,0 +1,120 @@ +--- +title: Map.prototype.has() +slug: Web/JavaScript/Reference/Global_Objects/Map/has +tags: + - ECMAScript 2015 + - JavaScript + - Map + - Method + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Map/has +--- +
{{JSRef}}
+ +

方法has() 返回一个bool值,用来表明map 中是否存在指定元素.

+ +

语法

+ +
myMap.has(key);
+ +

参数

+ +
+
key
+
必填. 用来检测是否存在指定元素的键值.
+
+ +

返回值

+ +
+
Boolean
+
如果指定元素存在于Map中,则返回true。其他情况返回false
+
+ +

案例

+ +

使用has方法

+ +
var myMap = new Map();
+myMap.set("bar", "foo");
+
+myMap.has("bar");  // returns true
+myMap.has("baz");  // returns false
+
+ +

规范列表

+ + + + + + + + + + + + + + +
规范名称StatusComment
{{SpecName('ES6', '#sec-map.prototype.has', 'Map.prototype.has')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
浏览器Chrome谷歌Firefox (Gecko)火狐Internet ExplorerOperaSafari
兼容版本38{{CompatGeckoDesktop("13.0")}}11257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
浏览器AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
兼容版本{{CompatNo}}38{{CompatGeckoMobile("13.0")}}{{CompatNo}}{{CompatNo}}8
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/index.html new file mode 100644 index 0000000000..b84dfb2304 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/index.html @@ -0,0 +1,340 @@ +--- +title: Map +slug: Web/JavaScript/Reference/Global_Objects/Map +tags: + - ECMAScript6 + - JavaScript + - Map +translation_of: Web/JavaScript/Reference/Global_Objects/Map +--- +
+
{{JSRef}}
+
+ +

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者{{Glossary("Primitive", "原始值")}}) 都可以作为一个键或一个值。

+ +
+
+ +

描述

+ +

一个Map对象在迭代时会根据对象中元素的插入顺序来进行 — 一个  {{jsxref("Statements/for...of", "for...of")}} 循环在每次迭代后会返回一个形式为[key,value]的数组。

+ +

键的相等(Key equality)

+ + + +

Objects 和 maps 的比较

+ +

{{jsxref("Object", "Objects")}} 和 Maps 类似的是,它们都允许你按键存取一个值、删除键、检测一个键是否绑定了值。因此(并且也没有其他内建的替代方式了)过去我们一直都把对象当成 Maps 使用。不过 Maps 和 Objects 有一些重要的区别,在下列情况里使用 Map 会是更好的选择:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MapObject
意外的键Map 默认情况不包含任何键。只包含显式插入的键。 +

一个 Object 有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。

+ +
+

注意: 虽然 ES5 开始可以用 Object.create(null) 来创建一个没有原型的对象,但是这种用法不太常见。

+
+
键的类型一个 Map的键可以是任意值,包括函数、对象或任意基本类型。一个Object 的键必须是一个 {{jsxref("String")}} 或是{{jsxref("Symbol")}}。
键的顺序 +

Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。

+
+

一个 Object 的键是无序的

+ +
+

注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。

+
+
Size Map 的键值对个数可以轻易地通过{{jsxref("Map.prototype.size", "size")}} 属性获取Object 的键值对个数只能手动计算
迭代Mapiterable 的,所以可以直接被迭代。迭代一个Object需要以某种方式获取它的键然后才能迭代。
性能 +

在频繁增删键值对的场景下表现更好。

+
+

在频繁添加和删除键值对的场景下未作出优化。

+
+ +

构造函数

+ +
+
{{jsxref("Global_Objects/Map/Map", "Map()")}}
+
创建 Map 对象
+
+ +

属性

+ +
+
Map.length
+
属性 length 的值为 0 。
+ 想要计算一个Map 中的条目数量, 使用 {{jsxref("Map.prototype.size")}}.
+
{{jsxref("Map.@@species", "get Map[@@species]")}}
+
本构造函数用于创建派生对象。
+
{{jsxref("Map.prototype")}}
+
表示 Map 构造器的原型。 允许添加属性从而应用于所有的 Map 对象。
+
+ +

Map 实例

+ +

所有的 Map 对象实例都会继承 {{jsxref("Map.prototype")}}。

+ +

属性

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/Map/prototype','属性')}}

+ +

方法

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/Map/prototype','方法')}}

+ +

示例

+ +

使用 Map 对象

+ +
let myMap = new Map();
+
+let keyObj = {};
+let keyFunc = function() {};
+let keyString = 'a string';
+
+// 添加键
+myMap.set(keyString, "和键'a string'关联的值");
+myMap.set(keyObj, "和键keyObj关联的值");
+myMap.set(keyFunc, "和键keyFunc关联的值");
+
+myMap.size; // 3
+
+// 读取值
+myMap.get(keyString);    // "和键'a string'关联的值"
+myMap.get(keyObj);       // "和键keyObj关联的值"
+myMap.get(keyFunc);      // "和键keyFunc关联的值"
+
+myMap.get('a string');   // "和键'a string'关联的值"
+                         // 因为keyString === 'a string'
+myMap.get({});           // undefined, 因为keyObj !== {}
+myMap.get(function() {}); // undefined, 因为keyFunc !== function () {}
+ +

将 NaN 作为 Map 的键

+ +

NaN 也可以作为Map对象的键。虽然 NaN 和任何值甚至和自己都不相等(NaN !== NaN 返回true),但下面的例子表明,NaN作为Map的键来说是没有区别的:

+ +
let myMap = new Map();
+myMap.set(NaN, "not a number");
+
+myMap.get(NaN); // "not a number"
+
+let otherNaN = Number("foo");
+myMap.get(otherNaN); // "not a number"
+
+ +

使用 for..of 方法迭代 Map

+ +

Map可以使用for..of循环来实现迭代:

+ +
let myMap = new Map();
+myMap.set(0, "zero");
+myMap.set(1, "one");
+for (let [key, value] of myMap) {
+  console.log(key + " = " + value);
+}
+// 将会显示两个log。一个是"0 = zero"另一个是"1 = one"
+
+for (let key of myMap.keys()) {
+  console.log(key);
+}
+// 将会显示两个log。 一个是 "0" 另一个是 "1"
+
+for (let value of myMap.values()) {
+  console.log(value);
+}
+// 将会显示两个log。 一个是 "zero" 另一个是 "one"
+
+for (let [key, value] of myMap.entries()) {
+  console.log(key + " = " + value);
+}
+// 将会显示两个log。 一个是 "0 = zero" 另一个是 "1 = one"
+ +

使用 forEach() 方法迭代 Map

+ +

Map也可以通过forEach()方法迭代:

+ +
myMap.forEach(function(value, key) {
+  console.log(key + " = " + value);
+})
+// 将会显示两个logs。 一个是 "0 = zero" 另一个是 "1 = one"
+
+ +

Map 与数组的关系

+ +
let kvArray = [["key1", "value1"], ["key2", "value2"]];
+
+// 使用常规的Map构造函数可以将一个二维键值对数组转换成一个Map对象
+let myMap = new Map(kvArray);
+
+myMap.get("key1"); // 返回值为 "value1"
+
+// 使用Array.from函数可以将一个Map对象转换成一个二维键值对数组
+console.log(Array.from(myMap)); // 输出和kvArray相同的数组
+
+// 更简洁的方法来做如上同样的事情,使用展开运算符
+console.log([...myMap]);
+
+// 或者在键或者值的迭代器上使用Array.from,进而得到只含有键或者值的数组
+console.log(Array.from(myMap.keys())); // 输出 ["key1", "key2"]
+
+ +

复制或合并 Maps

+ +

Map 能像数组一样被复制:

+ +
let original = new Map([
+  [1, 'one']
+]);
+
+let clone = new Map(original);
+
+console.log(clone.get(1)); // one
+console.log(original === clone); // false. 浅比较 不为同一个对象的引用
+
+ +
+

重要:请记住,数据本身未被克隆。

+
+ +

Map对象间可以进行合并,但是会保持键的唯一性。

+ +
let first = new Map([
+  [1, 'one'],
+  [2, 'two'],
+  [3, 'three'],
+]);
+
+let second = new Map([
+  [1, 'uno'],
+  [2, 'dos']
+]);
+
+// 合并两个Map对象时,如果有重复的键值,则后面的会覆盖前面的。
+// 展开运算符本质上是将Map对象转换成数组。
+let merged = new Map([...first, ...second]);
+
+console.log(merged.get(1)); // uno
+console.log(merged.get(2)); // dos
+console.log(merged.get(3)); // three
+ +

Map对象也能与数组合并:

+ +
let first = new Map([
+  [1, 'one'],
+  [2, 'two'],
+  [3, 'three'],
+]);
+
+let second = new Map([
+  [1, 'uno'],
+  [2, 'dos']
+]);
+
+// Map对象同数组进行合并时,如果有重复的键值,则后面的会覆盖前面的。
+let merged = new Map([...first, ...second, [1, 'eins']]);
+
+console.log(merged.get(1)); // eins
+console.log(merged.get(2)); // dos
+console.log(merged.get(3)); // three
+ +

使用说明

+ +

请注意!为Map设置对象属性也是可以的,但是可能引起大量的混乱。

+ +

所以,你还是可以这样做...

+ +
let wrongMap = new Map()
+wrongMap['bla'] = 'blaa'
+wrongMap['bla2'] = 'blaaa2'
+
+console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }
+
+ +

...但是,这样做的话,它的行为会不符合预期:

+ +
wrongMap.has('bla')    // false
+wrongMap.delete('bla') // false
+console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }
+ +

无论如何,和正确用法比较起来,几乎没有什么不同: 

+ +
let myMap = new Map()
+myMap.set('bla','blaa')
+myMap.set('bla2','blaa2')
+console.log(myMap)  // Map { 'bla' => 'blaa', 'bla2' => 'blaa2' }
+
+myMap.has('bla')    // true
+myMap.delete('bla') // true
+console.log(myMap)  // Map { 'bla2' => 'blaa2' }
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-map-objects', 'Map')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Map")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/keys/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/keys/index.html new file mode 100644 index 0000000000..5d27dffc82 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/keys/index.html @@ -0,0 +1,79 @@ +--- +title: Map.prototype.keys() +slug: Web/JavaScript/Reference/Global_Objects/Map/keys +tags: + - ECMAScript6 + - Iterator + - JavaScript + - Map + - Method + - Prototype + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Map/keys +--- +
{{JSRef}}
+ +

keys() 返回一个引用的 Iterator 对象。它包含按照顺序插入 Map 对象中每个元素的key值。

+ +
{{EmbedInteractiveExample("pages/js/map-prototype-keys.html")}}
+ + + +

语法

+ +
myMap.keys()
+ +

返回值

+ +

一个存在引用关系的 {{jsxref("Map")}} iterator 对象.

+ +

例子

+ +

使用 keys()

+ +
var myMap = new Map();
+myMap.set("0", "foo");
+myMap.set(1, "bar");
+myMap.set({}, "baz");
+
+var mapIter = myMap.keys();
+
+console.log(mapIter.next().value); // "0"
+console.log(mapIter.next().value); // 1
+console.log(mapIter.next().value); // Object
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-map.prototype.keys', 'Map.prototype.keys')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype.keys', 'Map.prototype.keys')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Map.keys")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/map/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/map/index.html new file mode 100644 index 0000000000..643f5b2b4d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/map/index.html @@ -0,0 +1,57 @@ +--- +title: Map() 构造函数 +slug: Web/JavaScript/Reference/Global_Objects/Map/Map +translation_of: Web/JavaScript/Reference/Global_Objects/Map/Map +--- +
{{JSRef}}
+ +

Map() 构造函数 创建 {{jsxref("Map")}} 对象.

+ +

语法

+ +
new Map([iterable])
+ +

参数

+ +
+
iterable
+
Iterable 可以是一个{{jsxref("Array", "数组")}}或者其他 iterable 对象,其元素为键值对(两个元素的数组,例如: [[ 1, 'one' ],[ 2, 'two' ]])。 每个键值对都会添加到新的 Map。null 会被当做 undefined。
+
+ +

示例

+ +
let myMap = new Map([
+  [1, 'one'],
+  [2, 'two'],
+  [3, 'three'],
+])
+
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-map-constructor', 'Map constructor')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Map.Map")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/prototype/index.html new file mode 100644 index 0000000000..99c2f0de08 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/prototype/index.html @@ -0,0 +1,130 @@ +--- +title: Map.prototype +slug: Web/JavaScript/Reference/Global_Objects/Map/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Map +--- +
{{JSRef}}
+ +

Map.prototype 属性表示 {{jsxref("Map")}}构造函数的原型对象。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

{{jsxref("Map")}} 实例继承自{{jsxref("Map.prototype")}}。你可以使用这个构造函数的原型对象来给所有的Map实例添加属性或者方法。

+ +

属性

+ +
+
Map.prototype.constructor
+
返回一个函数,它创建了实例的原型。默认是{{jsxref("Map")}}函数。
+
{{jsxref("Map.prototype.size")}}
+
返回Map对象的键/值对的数量。
+
+ +

方法

+ +
+
{{jsxref("Map.prototype.clear()")}}
+
移除Map对象的所有键/值对 。
+
{{jsxref("Map.delete", "Map.prototype.delete(key)")}}
+
如果 Map 对象中存在该元素,则移除它并返回 true;否则如果该元素不存在则返回 false。随后调用 Map.prototype.has(key) 将返回 false
+
{{jsxref("Map.prototype.entries()")}}
+
返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组
+
{{jsxref("Map.forEach", "Map.prototype.forEach(callbackFn[, thisArg])")}}
+
按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。如果为forEach提供了thisArg,它将在每次回调中作为this值。
+
{{jsxref("Map.get", "Map.prototype.get(key)")}}
+
返回键对应的值,如果不存在,则返回undefined。
+
{{jsxref("Map.has", "Map.prototype.has(key)")}}
+
返回一个布尔值,表示Map实例是否包含键对应的值。
+
{{jsxref("Map.prototype.keys()")}}
+
返回一个新的 Iterator对象, 它按插入顺序包含了Map对象中每个元素的
+
{{jsxref("Map.set", "Map.prototype.set(key, value)")}}
+
设置Map对象中键的值。返回该Map对象。
+
{{jsxref("Map.prototype.values()")}}
+
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的
+
{{jsxref("Map.@@iterator", "Map.prototype[@@iterator]()")}}
+
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{ CompatGeckoDesktop("13") }}11257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}38{{CompatGeckoMobile("13")}}{{CompatNo}}{{CompatNo}} +

8

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/set/index.html new file mode 100644 index 0000000000..8184278bc3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/set/index.html @@ -0,0 +1,96 @@ +--- +title: Map.prototype.set() +slug: Web/JavaScript/Reference/Global_Objects/Map/set +tags: + - ECMAScript6 + - JavaScript + - Map + - Method + - Prototype + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Map/set +--- +

{{JSRef}}

+ +

set() 方法为 Map 对象添加或更新一个指定了键(key)和值(value)的(新)键值对。

+ +
{{EmbedInteractiveExample("pages/js/map-prototype-set.html")}}
+ + + +

语法

+ +
myMap.set(key, value);
+ +

参数

+ +
+
key
+
要添加至相应 Map 对象的元素的键。
+
value
+
要添加至相应 Map 对象的元素的值。
+
+ +

返回值

+ +

Map 对象

+ +

示例

+ +

使用 set 方法

+ +
var myMap = new Map();
+
+// 将一个新元素添加到 Map 对象
+myMap.set("bar", "foo");
+myMap.set(1, "foobar");
+
+// 在Map对象中更新某个元素的值
+myMap.set("bar", "baz");
+
+ +

链式使用 set 方法

+ +

因为 Set() 方法返回 Map 对象本身,所以你可以像下面这样链式调用它:

+ +
// Add new elements to the map with chaining.
+myMap.set('bar', 'foo')
+     .set(1, 'foobar')
+     .set(2, 'baz');
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-map.prototype.set', 'Map.prototype.set')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype.set', 'Map.prototype.set')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Map.set")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/size/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/size/index.html new file mode 100644 index 0000000000..14fb449e92 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/size/index.html @@ -0,0 +1,77 @@ +--- +title: Map.prototype.size +slug: Web/JavaScript/Reference/Global_Objects/Map/size +tags: + - ECMAScript 2015 + - JavaScript + - Map + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Map/size +--- +
{{JSRef}}
+ +

size 是可访问属性,用于返回 一个{{jsxref("Map")}} 对象的成员数量。

+ +

{{EmbedInteractiveExample("pages/js/map-prototype-size.html")}}

+ +

这个示例源码保存在GitHub:https://github.com/mdn/interactive-examples。如果你想贡献代码,修改后在GitHub上发推送请求给我们。

+ +

 

+ +

描述

+ +

size 属性的值是一个整数,表示 Map 对象有多少个键值对。size 是只读属性,用set 方法修改size返回 undefined,即不能改变它的值。

+ +

示例

+ +
var myMap = new Map();
+myMap.set("a", "alpha");
+myMap.set("b", "beta");
+myMap.set("g", "gamma");
+
+myMap.size // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-map.prototype.size', 'Map.prototype.size')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-get-map.prototype.size', 'Map.prototype.size')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +

此页的兼容性表格请查阅:https://github.com/mdn/browser-compat-data 
+ 如果你想更新数据,请在GitHub上给我们发推送请求。

+ +
+

异常提醒

+
+ + + +

相关阅读

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/values/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/values/index.html new file mode 100644 index 0000000000..30336e98ce --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/map/values/index.html @@ -0,0 +1,112 @@ +--- +title: Map.prototype.values() +slug: Web/JavaScript/Reference/Global_Objects/Map/values +translation_of: Web/JavaScript/Reference/Global_Objects/Map/values +--- +
values() 方法返回一个新的Iterator对象。它包含按顺序插入Map对象中每个元素的value值。
+ +
 
+ +

语法

+ +
myMap.values()
+ +

返回值

+ +

一个新的 Map 可迭代对象.

+ +

例子

+ +

使用 values()

+ +
var myMap = new Map();
+myMap.set("0", "foo");
+myMap.set(1, "bar");
+myMap.set({}, "baz");
+
+var mapIter = myMap.values();
+
+console.log(mapIter.next().value); // "foo"
+console.log(mapIter.next().value); // "bar"
+console.log(mapIter.next().value); // "baz"
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES6', '#sec-map.prototype.values', 'Map.prototype.values')}}{{Spec2('ES6')}}初始定义
{{SpecName('ESDraft', '#sec-map.prototype.values', 'Map.prototype.values')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{ CompatGeckoDesktop("20") }}{{CompatNo}}257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}38{{ CompatGeckoMobile("20") }}{{CompatNo}}{{CompatNo}}8
+
+ +

查看

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/abs/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/abs/index.html new file mode 100644 index 0000000000..13f5f96b79 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/abs/index.html @@ -0,0 +1,125 @@ +--- +title: Math.abs() +slug: Web/JavaScript/Reference/Global_Objects/Math/abs +translation_of: Web/JavaScript/Reference/Global_Objects/Math/abs +--- +
{{JSRef("Global_Objects", "Math")}}
+ +

Math.abs(x) 函数返回指定数字 “x“ 的绝对值。如下:

+ +

Math.abs(x)=|x|={xifx0-xifx<0{\mathtt{\operatorname{Math.abs}(x)}} = {|x|} = \begin{cases} x & \text{if} \quad x \geq 0 \\ -x & \text{if} \quad x < 0 \end{cases}

+ +

语法

+ +
Math.abs(x);
+ +

参数

+ +
+
x
+
一个数值
+
+ +

说明

+ +

由于 Math.abs()  Math 中的一个静态方法,你应该通过 Math.abs() 调用。(Math 不是构造器)

+ +

示例

+ +

Math.abs()函数的行为

+ +

传入一个非数字形式的字符串或者 undefined/empty 变量,将返回 NaN。传入 null 将返回 0。

+ +
Math.abs('-1');     // 1
+Math.abs(-2);       // 2
+Math.abs(null);     // 0
+Math.abs("string"); // NaN
+Math.abs();         // NaN
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.1', 'Math.abs')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.abs', 'Math.abs')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/acos/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/acos/index.html new file mode 100644 index 0000000000..7ff574d177 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/acos/index.html @@ -0,0 +1,115 @@ +--- +title: Math.acos() +slug: Web/JavaScript/Reference/Global_Objects/Math/acos +translation_of: Web/JavaScript/Reference/Global_Objects/Math/acos +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.acos() 返回一个数的反余弦值(单位为弧度),即:

+

x[-1;1],Math.acos(x)=arccos(x)= the unique y[0;π]such thatcos(y)=x\forall x \in [{-1};1],\;\mathtt{\operatorname{Math.acos}(x)} = \arccos(x) = \text{ the unique } \; y \in [0; \pi] \, \text{such that} \; \cos(y) = x

+

语法

+
Math.acos(x) 
+

参数

+
+
+ x
+
+ 一个数值
+
+

描述

+

acos 方法以 -1 到 1 的一个数为参数,返回一个 0 到 pi (弧度)的数值。如果传入的参数值超出了限定的范围,将返回 NaN

+

由于 acosMath 的静态方法,所以应该像这样使用:Math.acos(),而不是作为你创建的 Math 实例的属性(Math 不是一个构造函数)。

+

示例

+

例子:使用 Math.acos

+
Math.acos(-2);  // NaN
+Math.acos(-1);  // 3.141592653589793
+Math.acos(0);   // 1.5707963267948966
+Math.acos(0.5); // 1.0471975511965979
+Math.acos(1);   // 0
+Math.acos(2);   // NaN
+
+

对于小于 -1 或大于 1 的值,Math.acos 返回 NaN

+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.2', 'Math.acos')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.acos', 'Math.acos')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/asin/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/asin/index.html new file mode 100644 index 0000000000..de7ebe61b3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/asin/index.html @@ -0,0 +1,114 @@ +--- +title: Math.asin() +slug: Web/JavaScript/Reference/Global_Objects/Math/asin +translation_of: Web/JavaScript/Reference/Global_Objects/Math/asin +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.asin() 方法返回一个数值的反正弦(单位为弧度),即:

+

x[-1;1],Math.asin(x)=arcsin(x)= the unique y[-π2;π2]such thatsin(y)=x\forall x \in [{-1};1],\;\mathtt{\operatorname{Math.asin}(x)} = \arcsin(x) = \text{ the unique } \; y \in \left[-\frac{\pi}{2}; \frac{\pi}{2}\right] \, \text{such that} \; \sin(y) = x

+

语法

+
Math.asin(x)
+

参数

+
+
+ x
+
+ 一个数值
+
+

描述

+

asin 方法接受 -1 到 1 之间的数值作为参数,返回一个介于 -π2-\frac{\pi}{2} 到 π2\frac{\pi}{2} 弧度的数值。如果接受的参数值超出范围,则返回 NaN

+

由于 asinMath 的静态方法,所有应该像这样使用:Math.asin(),而不是作为你创建的 Math 实例的方法。

+

示例

+

例子:使用 Math.asin()

+
Math.asin(-2);  // NaN
+Math.asin(-1);  // -1.5707963267948966 (-pi/2)
+Math.asin(0);   // 0
+Math.asin(0.5); // 0.5235987755982989
+Math.asin(1);   // 1.570796326794897 (pi/2)
+Math.asin(2);   // NaN
+

对于小于 -1 或大于 1 的参数值,Math.asin 返回 NaN

+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.3', 'Math.asin')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.asin', 'Math.asin')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/asinh/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/asinh/index.html new file mode 100644 index 0000000000..2d7afa3b8f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/asinh/index.html @@ -0,0 +1,87 @@ +--- +title: Math.asinh() +slug: Web/JavaScript/Reference/Global_Objects/Math/asinh +translation_of: Web/JavaScript/Reference/Global_Objects/Math/asinh +--- +
{{JSRef}}
+ +

Math.asinh() 返回一个数值的反双曲正弦值,即:

+ +

Math.asinh(x)=arsinh(x)= the unique ysuch thatsinh(y)=x\mathtt{\operatorname{Math.asinh}(x)} = \operatorname{arsinh}(x) = \text{ the unique } \; y \; \text{such that} \; \sinh(y) = x

+ +
{{EmbedInteractiveExample("pages/js/math-asinh.html")}}
+ + + +

语法

+ +
Math.asinh(x)
+ +

参数

+ +
+
x
+
一个数值.
+
+ +

返回值

+ +

返回指定数值的反双曲正弦值.

+ +

描述

+ +

由于 asinh() 是 Math 的静态方法,所以应该像这样使用:Math.asinh(),而不是作为你创建的 Math 实例的方法(Math 不是一个构造函数)。

+ +

示例

+ +

    使用 Math.asinh()

+ +
Math.asinh(1);  // 0.881373587019543
+Math.asinh(0);  // 0
+
+ +

Polyfill

+ +

As a quick and dirty hack the expression arsinh(x)=ln(x+x2+1)\operatorname {arsinh} (x) = \ln \left(x + \sqrt{x^{2} + 1} \right) may be used directly for a coarse emulation by the following function:

+ +
Math.asinh = Math.asinh || function(x) {
+  if (x === -Infinity) {
+    return x;
+  } else {
+    return Math.log(x + Math.sqrt(x * x + 1));
+  }
+};
+
+ +

Been formally correct it suffers from a number of issues related to floating point computations. Accurate result requires special handling of positive/negative, small/large arguments as it done e.g. in glibc or GNU Scientific Library.

+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-math.asinh', 'Math.asinh')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Math.asinh")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/atan/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/atan/index.html new file mode 100644 index 0000000000..cd10d30644 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/atan/index.html @@ -0,0 +1,110 @@ +--- +title: Math.atan() +slug: Web/JavaScript/Reference/Global_Objects/Math/atan +translation_of: Web/JavaScript/Reference/Global_Objects/Math/atan +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.atan() 函数返回一个数值的反正切(以弧度为单位),即:

+

Math.atan(x)=arctan(x)= the unique y[-π2;π2]such thattan(y)=x\mathtt{\operatorname{Math.atan}(x)} = \arctan(x) = \text{ the unique } \; y \in \left[-\frac{\pi}{2}; \frac{\pi}{2}\right] \, \text{such that} \; \tan(y) = x

+

语法

+
Math.atan(x)
+

参数

+
+
+ x
+
+ 一个数值
+
+

描述

+

atan 返回一个 -π2-\frac{\pi}{2} 到 π2\frac{\pi}{2} 弧度之间的数值。

+

由于 atanMath 的静态方法,所以应该像这样使用:Math.atan(),而不是作为你创建的 Math 实例的方法。

+

示例

+

例子:使用 Math.atan

+
Math.atan(1);  // 0.7853981633974483
+Math.atan(0);  // 0
+
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.4', 'Math.atan')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.atan', 'Math.atan')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/atan2/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/atan2/index.html new file mode 100644 index 0000000000..7bf921655d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/atan2/index.html @@ -0,0 +1,140 @@ +--- +title: Math.atan2() +slug: Web/JavaScript/Reference/Global_Objects/Math/atan2 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/atan2 +--- +
{{JSRef("Global_Objects", "Math")}}
+ +

概述

+ +

Math.atan2() 返回从原点(0,0)到(x,y)点的线段与x轴正方向之间的平面角度(弧度值),也就是Math.atan2(y,x)

+ +

语法

+ +
Math.atan2(y, x) 
+ +

参数

+ +
+
y, x
+
数值
+
+ +

描述

+ +

atan2 方法返回一个 -pi 到 pi 之间的数值,表示点 (x, y) 对应的偏移角度。这是一个逆时针角度,以弧度为单位,正X轴和点 (x, y) 与原点连线 之间。注意此函数接受的参数:先传递 y 坐标,然后是 x 坐标。

+ +

atan2 接受单独的 x 和 y 参数,而 atan 接受两个参数的比值。

+ +

由于 atan2Math 的静态方法,所以应该像这样使用:Math.atan2(),而不是作为你创建的 Math 实例的方法。

+ +

示例

+ +

例子:使用 Math.atan2

+ +
Math.atan2(90, 15) // 1.4056476493802699
+Math.atan2(15, 90) // 0.16514867741462683
+
+Math.atan2( ±0, -0 )               // ±PI.
+Math.atan2( ±0, +0 )               // ±0.
+Math.atan2( ±0, -x )               // ±PI for x > 0.
+Math.atan2( ±0, x )                // ±0 for x > 0.
+Math.atan2( -y, ±0 )               // -PI/2 for y > 0.
+Math.atan2( y, ±0 )                // PI/2 for y > 0.
+Math.atan2( ±y, -Infinity )        // ±PI for finite y > 0.
+Math.atan2( ±y, +Infinity )        // ±0 for finite y > 0.
+Math.atan2( ±Infinity, x )         // ±PI/2 for finite x.
+Math.atan2( ±Infinity, -Infinity ) // ±3*PI/4.
+Math.atan2( ±Infinity, +Infinity ) // ±PI/4.
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.5', 'Math.atan2')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-math.atan2', 'Math.atan2')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/atanh/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/atanh/index.html new file mode 100644 index 0000000000..08af33d242 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/atanh/index.html @@ -0,0 +1,132 @@ +--- +title: Math.atanh() +slug: Web/JavaScript/Reference/Global_Objects/Math/atanh +translation_of: Web/JavaScript/Reference/Global_Objects/Math/atanh +--- +
{{JSRef}}
+ +

Math.atanh() 函数返回一个数值反双曲正切值, 即:

+ +

x(-1,1),Math.atanh(x)=arctanh(x)= the unique ysuch thattanh(y)=x\forall x \in \left( -1, 1 \right), \mathtt{\operatorname{Math.atanh}(x)} = \operatorname{arctanh}(x) = \text{ the unique } \; y \; \text{such that} \; \tanh(y) = x

+ +

语法

+ +
Math.atanh(x)
+ +

参数

+ +
+
x
+
一个数值
+
+ +

描述

+ +

由于 atanh() 是 Math 的静态方法,所以应该像这样使用:Math.atanh(),而不是作为你创建的 Math 实例的方法(Math 不是一个构造函数)。 

+ +

示例

+ +

使用 Math.atanh()

+ +
Math.atanh(-2);  // NaN
+Math.atanh(-1);  // -Infinity
+Math.atanh(0);   // 0
+Math.atanh(0.5); // 0.5493061443340548
+Math.atanh(1);   // Infinity
+Math.atanh(2);   // NaN
+
+ +

对于大于1或是小于-1的值,函数返回 {{jsxref("NaN")}} 。

+ +

Polyfill

+ +

For \left|x\right| < 1, we have \operatorname {artanh} (x) = \frac{1}{2}\ln \left( \frac{1 + x}{1 - x} \right) so this can be emulated by the following function:

+ +
Math.atanh = Math.atanh || function(x) {
+  return Math.log((1+x)/(1-x)) / 2;
+};
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-math.atanh', 'Math.atanh')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-math.atanh', 'Math.atanh')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("38")}}{{CompatGeckoDesktop("25")}}{{CompatNo}}{{CompatOpera("25")}}{{CompatSafari("7.1")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}8
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/cbrt/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/cbrt/index.html new file mode 100644 index 0000000000..d583caf717 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/cbrt/index.html @@ -0,0 +1,140 @@ +--- +title: Math.cbrt() +slug: Web/JavaScript/Reference/Global_Objects/Math/cbrt +translation_of: Web/JavaScript/Reference/Global_Objects/Math/cbrt +--- +
{{JSRef("Global_Objects", "Math")}}
+ +

概述

+ +

Math.cbrt() 函数返回任意数字的立方根.

+ +

语法

+ +
Math.cbrt(x)
+ +

参数

+ +
+
x
+
任意数字.
+
+ +

返回值

+ + + +

给定数字的立方根

+ + + +

描述

+ +

该方法为Math的静态方法,因此请直接通过Math.cbrt()方式调用.

+ +

而不是作为您创建的Math对象的方法(Math不是构造函数)。

+ +

cbrt 是 "cube root" 的缩写, 意思是立方根.

+ +

示例

+ +

使用 Math.cbrt()

+ +
Math.cbrt(NaN); // NaN
+Math.cbrt(-1); // -1
+Math.cbrt(-0); // -0
+Math.cbrt(-Infinity); // -Infinity
+Math.cbrt(0); // 0
+Math.cbrt(1); // 1
+Math.cbrt(Infinity); // Infinity
+Math.cbrt(null); // 0
+Math.cbrt(2);  // 1.2599210498948734
+ +

Polyfill

+ +

为了与旧版浏览器兼容, 可使用下方函数模拟cbrt():

+ +
if (!Math.cbrt) {
+  Math.cbrt = function(x) {
+    var y = Math.pow(Math.abs(x), 1/3);
+    return x < 0 ? -y : y;
+  };
+}
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-math.cbrt', 'Math.cbrt')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatGeckoDesktop("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ + + +

另请参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/ceil/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/ceil/index.html new file mode 100644 index 0000000000..9b316f075a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/ceil/index.html @@ -0,0 +1,164 @@ +--- +title: Math.ceil() +slug: Web/JavaScript/Reference/Global_Objects/Math/ceil +tags: + - JavaScript + - Math + - 参考 + - 数学 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/ceil +--- +
{{JSRef}}
+ +

Math.ceil() 函数返回大于或等于一个给定数字的最小整数。

+ +

Note: Math.ceil({{jsxref("null")}}) returns integer 0 and does not give a {{jsxref("NaN")}} error.

+ +
{{EmbedInteractiveExample("pages/js/math-ceil.html")}}
+ + + +

语法

+ +
Math.ceil(x)
+ +

参数

+ +
+
x
+
一个数值。
+
+

返回值

+ +

大于或等于给定数字的最小整数。

+
+
+ +

描述

+ +

由于 ceilMath 的静态方法,所以应该像这样使用:Math.ceil(),而不是作为你创建的 Math 实例的方法。

+ +

示例

+ +

使用 Math.ceil

+ +

下例展示了 Math.ceil() 的使用:

+ +
// Closure
+(function() {
+  /**
+   * Decimal adjustment of a number.
+   *
+   * @param {String}  type  The type of adjustment.
+   * @param {Number}  value The number.
+   * @param {Integer} exp   The exponent (the 10 logarithm of the adjustment base).
+   * @returns {Number} The adjusted value.
+   */
+  function decimalAdjust(type, value, exp) {
+    // If the exp is undefined or zero...
+    if (typeof exp === 'undefined' || +exp === 0) {
+      return Math[type](value);
+    }
+    value = +value;
+    exp = +exp;
+    // If the value is not a number or the exp is not an integer...
+    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
+      return NaN;
+    }
+    // Shift
+    value = value.toString().split('e');
+    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
+    // Shift back
+    value = value.toString().split('e');
+    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
+  }
+
+  // Decimal round
+  if (!Math.round10) {
+    Math.round10 = function(value, exp) {
+      return decimalAdjust('round', value, exp);
+    };
+  }
+  // Decimal floor
+  if (!Math.floor10) {
+    Math.floor10 = function(value, exp) {
+      return decimalAdjust('floor', value, exp);
+    };
+  }
+  // Decimal ceil
+  if (!Math.ceil10) {
+    Math.ceil10 = function(value, exp) {
+      return decimalAdjust('ceil', value, exp);
+    };
+  }
+})();
+
+// Round
+Math.round10(55.55, -1);   // 55.6
+Math.round10(55.549, -1);  // 55.5
+Math.round10(55, 1);       // 60
+Math.round10(54.9, 1);     // 50
+Math.round10(-55.55, -1);  // -55.5
+Math.round10(-55.551, -1); // -55.6
+Math.round10(-55, 1);      // -50
+Math.round10(-55.1, 1);    // -60
+// Floor
+Math.floor10(55.59, -1);   // 55.5
+Math.floor10(59, 1);       // 50
+Math.floor10(-55.51, -1);  // -55.6
+Math.floor10(-51, 1);      // -60
+// Ceil
+Math.ceil10(55.51, -1);    // 55.6
+Math.ceil10(51, 1);        // 60
+Math.ceil10(-55.59, -1);   // -55.5
+Math.ceil10(-59, 1);       // -50
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.8.2.6', 'Math.ceil')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-math.ceil', 'Math.ceil')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-math.ceil', 'Math.ceil')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Math.ceil")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/clz32/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/clz32/index.html new file mode 100644 index 0000000000..76501c5be5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/clz32/index.html @@ -0,0 +1,169 @@ +--- +title: Math.clz32() +slug: Web/JavaScript/Reference/Global_Objects/Math/clz32 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/clz32 +--- +
{{JSRef("Global_Objects", "Math")}}
+ +

概述

+ +

Math.clz32() 函数返回一个数字在转换成 32 无符号整形数字的二进制形式后, 开头的 0 的个数, 比如 1000000 转换成 32 位无符号整形数字的二进制形式后是 00000000000011110100001001000000, 开头的 0 的个数是 12 个, 则 Math.clz32(1000000) 返回 12.

+ +

语法

+ +
Math.clz32 (x)
+
+ +

参数

+ +
+
x
+
一个数字.
+
+ +

描述

+ +

"clz32" 是 CountLeadingZeroes32 的缩写.

+ +

如果 x 不是数字类型, 则它首先会被转换成数字类型, 然后再转成 32 位无符号整形数字. 

+ +

如果转换后的 32 位无符号整形数字是 0, 则返回 32, 因为此时所有位上都是 0.

+ +

NaN, Infinity, -Infinity 这三个数字转成 32 位无符号整形数字后都是 0.

+ +

这个函数主要用于那些编译目标为 JS 语言的系统中, 比如 Emscripten.

+ +

示例

+ +
Math.clz32(1)                // 31
+Math.clz32(1000)             // 22
+Math.clz32()                 // 32
+[NaN, Infinity, -Infinity, 0, -0, null, undefined, "foo", {}, []].filter(function (n) {
+  return Math.clz32(n) !== 32
+})                           // []
+Math.clz32(true)             // 31
+Math.clz32(3.5)              // 30
+
+ +

计算前导1的个数

+ +

目前javascript尚未提供Math.clon函数来计算前导1的个数(之所以叫“clon”而非“clo”,是因为“clo”与“clz”太过相似,特别对那些母语不是英语的人来说),但是你可以通过将一个数取反并将其作为Math.clz32的参数来实现clon函数。其中的原理非常简单,因为对1取反是0,反之亦然,所以用Math.clz32计算前导0的个数就变成计算前导1的个数。

+ +

先看以下代码:

+ +
var a = 32776;   // 00000000000000001000000000001000 (16个前导0)
+Math.clz32(a);   // 16
+
+var b = ~32776;  // 11111111111111110111111111110111 (对32776取反, 0个前导0)
+Math.clz32(b);   // 0 (相当于0个前导1)
+ +

通过以上方法,clon 函数可以定义如下:

+ +
var clz = Math.clz32;
+function clon(integer){
+    return clz(~integer);
+}
+ +

现在,我们可以进一步实现计算“尾随0”和“尾随1”的个数了。下面的ctrz函数将第一个1之后的高数位全部置为1然后取反,再用Math.clz32求得尾随0的个数。

+ +
var clz = Math.clz32;
+function ctrz(integer){ // 计算尾随0个数
+    // 1. 将第一个1之后的高数位全部置为1
+    // 00000000000000001000000000001000 => 11111111111111111111111111111000
+    integer |= integer << 16;
+    integer |= integer << 8;
+    integer |= integer << 4;
+    integer |= integer << 2;
+    integer |= integer << 1;
+    // 2. 然后,对该数取反,此时低位的1的个数即为所求
+    return 32 - clz(~integer) |0; // `|0`用于保证结果为整数
+}
+function ctron(integer){ // 计算尾随1个数
+    // JavaScript中没有移位补1的运算符
+    // 所以下面的代码是最快的
+    return ctrz(~integer);
+    /* 为了看起来比较对称,你也可以使用以下代码:
+       // 1. 将第一个0之后的高数位全部置为0
+       integer &= (integer << 16) | 0xffff;
+       integer &= (integer << 8 ) | 0x00ff;
+       integer &= (integer << 4 ) | 0x000f;
+       integer &= (integer << 2 ) | 0x0003;
+       integer &= (integer << 1 ) | 0x0001;
+       // 2. 然后,对该数取反,此时低位的0的个数即为所求
+       return 32 - clon(~integer) |0;
+    */
+}
+ +

将以上函数改写成 ASM.JS模块——然后,你就可以去跟别人炫耀了!ASM.JS就是用来干这个的。

+ +
var countTrailsMethods = (function(stdlib, foreign, heap) {
+    "use asm";
+    var clz = stdlib.Math.clz32;
+    function ctrz(integer) { // 计算尾随0个数
+        integer = integer | 0; // 确保是整数
+        // 1. 将第一个1之后的高数位全部置为1
+        // ASMjs中不允许^=、&=、和|=
+        integer = integer | (integer << 16);
+        integer = integer | (integer << 8);
+        integer = integer | (integer << 4);
+        integer = integer | (integer << 2);
+        integer = integer | (integer << 1);
+        // 2. 然后,对该数取反,此时低位的1的个数即为所求
+        return 32 - clz(~integer) |0;
+    }
+    function ctron(integer) { // 计算尾随1个数
+        integer = integer | 0; // 确保是整数
+        return ctrz(~integer) |0;
+    }
+    // 蛋疼的是,ASM.JS必须使用糟糕的object类型:
+    // unfourtunately, ASM.JS demands slow crummy objects:
+    return {a: ctrz, b: ctron};
+})(window, null, null);
+var ctrz = countTrailsMethods.a;
+var ctron = countTrailsMethods.b;
+ +

Polyfill

+ +

这个polyfill效率最高。

+ +
if (!Math.clz32) Math.clz32 = (function(log, LN2){
+  return function(x) {
+    var asUint = x >>> 0; // 将x转换为Uint32类型
+    if (asUint === 0) {
+      return 32;
+    }
+    return 31 - (log(asUint) / LN2 | 0) |0; // "| 0"相当于Math.floor
+  };
+})(Math.log, Math.LN2);
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-Math.clz32', 'Math.clz32')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Math.clz32")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/cos/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/cos/index.html new file mode 100644 index 0000000000..55b273cad1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/cos/index.html @@ -0,0 +1,106 @@ +--- +title: Math.cos() +slug: Web/JavaScript/Reference/Global_Objects/Math/cos +translation_of: Web/JavaScript/Reference/Global_Objects/Math/cos +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.cos() 函数返回一个数值的余弦值。

+

语法

+
Math.cos(x)
+

参数

+
+
+ x
+
+ 一个以弧度为单位的数值。
+
+

描述

+

cos 方法返回一个 -1 到 1 之间的数值,表示角度(单位:弧度)的余弦值。

+

由于 cosMath 的静态方法,所以应该像这样使用:Math.cos(),而不是作为你创建的 Math 实例的方法。

+

示例

+

例子:使用 Math.cos

+
Math.cos(0);           // 1
+Math.cos(1);           // 0.5403023058681398
+
+Math.cos(Math.PI);     // -1
+Math.cos(2 * Math.PI); // 1
+
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.7', 'Math.cos')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.cos', 'Math.cos')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/cosh/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/cosh/index.html new file mode 100644 index 0000000000..cd5e578571 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/cosh/index.html @@ -0,0 +1,130 @@ +--- +title: Math.cosh() +slug: Web/JavaScript/Reference/Global_Objects/Math/cosh +translation_of: Web/JavaScript/Reference/Global_Objects/Math/cosh +--- +
{{JSRef}}
+ +

Math.cosh() 函数返回数值的双曲余弦函数, 可用 {{jsxref("Math.E", "constant e", "", 1)}} 表示:

+ +

Math.cosh(x)=ex+e-x2\mathtt{\operatorname{Math.cosh(x)}} = \frac{e^x + e^{-x}}{2}

+ +

Syntax

+ +
Math.cosh(x)
+ +

参数

+ +
+
x
+
数值.
+
+ +

描述

+ +

由于cosh() 是Math的静态函数, 只需通过Math.cosh() 调用,而不用通过创建Math对象来调用.

+ +

示例

+ +

使用 Math.cosh()

+ +
Math.cosh(0);  // 1
+Math.cosh(1);  // 1.5430806348152437
+Math.cosh(-1); // 1.5430806348152437
+
+ +

Polyfill

+ +

可通过 {{jsxref("Math.exp()")}} 函数模拟实现:

+ +
Math.cosh = Math.cosh || function(x) {
+  return (Math.exp(x) + Math.exp(-x)) / 2;
+}
+
+ +

或只调用一次 {{jsxref("Math.exp()")}} 函数:

+ +
Math.cosh = Math.cosh || function(x) {
+  var y = Math.exp(x);
+  return (y + 1 / y) / 2;
+};
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-math.cosh', 'Math.cosh')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("38")}}{{CompatGeckoDesktop("25")}}{{CompatNo}}{{CompatOpera("25")}}{{CompatSafari("7.1")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}8
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/e/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/e/index.html new file mode 100644 index 0000000000..ffa4251bac --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/e/index.html @@ -0,0 +1,99 @@ +--- +title: Math.E +slug: Web/JavaScript/Reference/Global_Objects/Math/E +translation_of: Web/JavaScript/Reference/Global_Objects/Math/E +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.E 属性表示自然对数的底数(或称为基数),e,约等于 2.718。

+

Math.E=e2.718\mathtt{\mi{Math.E}} = e \approx 2.718

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

由于 EMath 对象的静态属性,所以应该像这样使用:Math.E,而不是作为你创建的 Math 实例对象的属性(Math 不是构造函数)。

+

示例

+

例子:使用 Math.E

+

下面的函数返回 e:

+
function getNapier() {
+   return Math.E
+}
+
+getNapier() // 2.718281828459045
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.1.1', 'Math.E')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.e', 'Math.E')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/exp/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/exp/index.html new file mode 100644 index 0000000000..6295073e83 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/exp/index.html @@ -0,0 +1,105 @@ +--- +title: Math.exp() +slug: Web/JavaScript/Reference/Global_Objects/Math/exp +translation_of: Web/JavaScript/Reference/Global_Objects/Math/exp +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.exp() 函数返回 exx 表示参数,e欧拉常数(Euler's constant),自然对数的底数。

+

语法

+
Math.exp(x)
+

参数

+
+
+ x
+
+ 一个数值
+
+

描述

+

由于 expMath 的静态方法,所以应该像这样使用:Math.exp(),而不是作为你创建的 Math 实例的方法。

+

示例

+

例子:使用 Math.exp

+
Math.exp(-1); // 0.36787944117144233
+Math.exp(0);  // 1
+Math.exp(1);  // 2.718281828459045
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.8', 'Math.exp')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.exp', 'Math.exp')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/expm1/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/expm1/index.html new file mode 100644 index 0000000000..74502e9d83 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/expm1/index.html @@ -0,0 +1,119 @@ +--- +title: Math.expm1() +slug: Web/JavaScript/Reference/Global_Objects/Math/expm1 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/expm1 +--- +
{{JSRef("Global_Objects", "Math")}}
+ +

概述

+ +

Math.expm1() 函数返回 Ex - 1, 其中 x 是该函数的参数, E 是自然对数的底数 2.718281828459045.

+ +

语法

+ +
Math.expm1(x)
+ +

参数

+ +
+
x
+
任意数字.
+
+ +

描述

+ +

参数 x 会被自动类型转换成 number 类型.

+ +

expm1 是 "exponent minus 1" 的缩写.

+ +

示例

+ +
Math.expm1(1)     // 1.7182818284590453
+Math.expm1(-38)   // -1
+Math.expm1("-38") // -1
+Math.expm1("foo") // NaN
+
+ +

Polyfill

+ +

因为我们已经有了 Math.exp 函数, 所以很容易 polyfill.

+ +
Math.expm1 = Math.expm1 || function (x) {
+    return Math.exp(x) - 1
+}
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-math.expm1', 'Math.expm1')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatGeckoDesktop("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/floor/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/floor/index.html new file mode 100644 index 0000000000..f41d9aedfc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/floor/index.html @@ -0,0 +1,222 @@ +--- +title: Math.floor() +slug: Web/JavaScript/Reference/Global_Objects/Math/floor +tags: + - Math.floor() + - 向下取整 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/floor +--- +
{{JSRef}}
+ +

Math.floor() 返回小于或等于一个给定数字的最大整数。

+ +
+

Note:  可以理解 Math.floor()为向下取整

+
+ +

语法

+ +
Math.floor(x) 
+ +

参数

+ +
+
x
+
一个数字。
+
+

返回值 

+ +

一个表示小于或等于指定数字的最大整数的数字。

+
+
+ +

描述

+ +

由于 floorMath 的一个静态方法,你总是应该像这样使用它 Math.floor(),而不是作为你创建的一个Math对象的一种方法(Math不是一个构造函数)。

+ +

示例

+ +

例子:使用 Math.floor

+ +
Math.floor( 45.95);
+// 45
+Math.floor( 45.05);
+// 45
+Math.floor( 4 );
+// 4
+Math.floor(-45.05);
+// -46
+Math.floor(-45.95);
+// -46
+
+
+ +

例子:十进制调整

+ +
// Closure
+(function(){
+
+	/**
+	 * Decimal adjustment of a number.
+	 *
+	 * @param	{String}	type	The type of adjustment.
+	 * @param	{Number}	value	The number.
+	 * @param	{Integer}	exp		The exponent (the 10 logarithm of the adjustment base).
+	 * @returns	{Number}			The adjusted value.
+	 */
+	function decimalAdjust(type, value, exp) {
+		// If the exp is undefined or zero...
+		if (typeof exp === 'undefined' || +exp === 0) {
+			return Math[type](value);
+		}
+		value = +value;
+		exp = +exp;
+		// If the value is not a number or the exp is not an integer...
+		if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
+			return NaN;
+		}
+		// Shift
+		value = value.toString().split('e');
+		value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
+		// Shift back
+		value = value.toString().split('e');
+		return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
+	}
+
+	// Decimal round
+	if (!Math.round10) {
+		Math.round10 = function(value, exp) {
+			return decimalAdjust('round', value, exp);
+		};
+	}
+	// Decimal floor
+	if (!Math.floor10) {
+		Math.floor10 = function(value, exp) {
+			return decimalAdjust('floor', value, exp);
+		};
+	}
+	// Decimal ceil
+	if (!Math.ceil10) {
+		Math.ceil10 = function(value, exp) {
+			return decimalAdjust('ceil', value, exp);
+		};
+	}
+
+})();
+
+// Round
+Math.round10(55.55, -1); // 55.6
+Math.round10(55.549, -1); // 55.5
+Math.round10(55, 1); // 60
+Math.round10(54.9, 1); // 50
+Math.round10(-55.55, -1); // -55.5
+Math.round10(-55.551, -1); // -55.6
+Math.round10(-55, 1); // -50
+Math.round10(-55.1, 1); // -60
+// Floor
+Math.floor10(55.59, -1); // 55.5
+Math.floor10(59, 1); // 50
+Math.floor10(-55.51, -1); // -55.6
+Math.floor10(-51, 1); // -60
+// Ceil
+Math.ceil10(55.51, -1); // 55.6
+Math.ceil10(51, 1); // 60
+Math.ceil10(-55.59, -1); // -55.5
+Math.ceil10(-59, 1); // -50
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.9', 'Math.floor')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-math.floor', 'Math.floor')}} {{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-math.floor', 'Math.floor')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/fround/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/fround/index.html new file mode 100644 index 0000000000..022e84dbb6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/fround/index.html @@ -0,0 +1,154 @@ +--- +title: Math.fround() +slug: Web/JavaScript/Reference/Global_Objects/Math/fround +translation_of: Web/JavaScript/Reference/Global_Objects/Math/fround +--- +
{{JSRef("Global_Objects", "Math")}}
+ +

概述

+ +

Math.fround() 可以将任意的数字转换为离它最近的单精度浮点数形式的数字。

+ +

语法

+ +
Math.fround(doubleFloat)
+ +

参数

+ +
+
doubleFloat
+
一个 {{jsxref("Number")}}。若参数为非数字类型,则会被转投成数字。无法转换时,设置成{{jsxref("NaN")}}。
+
+ +

返回值

+ +

指定数字最接近的32位单精度浮点数表示。

+ +

描述

+ +

JavaScript 内部使用64位的双浮点数字,支持很高的精度。但是,有时你需要用32位浮点数字,比如你从一个{{jsxref("Float32Array")}} 读取值时。这时会产生混乱:检查一个64位浮点数和一个32位浮点数是否相等会失败,即使二个数字几乎一模一样。

+ +

要解决这个问题,可以使用 Math.fround() 来将64位的浮点数转换为32位浮点数。在内部,JavaScript 继续把这个数字作为64位浮点数看待,仅仅是在尾数部分的第23位执行了“舍入到偶数”的操作,并将后续的尾数位设置为0。如果数字超出32位浮点数的范围,则返回 {{jsxref("Infinity")}} 或 -Infinity

+ +

因为fround()Math 的静态方法,你必须通过 Math.fround() 来使用,而不是调用你创建的Math 对象的一个实例方法(Math不是一个构造函数)。

+ +

示例

+ +

使用 Math.fround()

+ +

数字1.5可以在二进制数字系统中精确表示,32位和64位的值相同:

+ +
Math.fround(1.5); // 1.5
+Math.fround(1.5) === 1.5; // true
+ +

但是,数字1.337却无法在二进制数字系统中精确表示,所以32位和64位的值是不同的:

+ +
Math.fround(1.337); // 1.3370000123977661
+Math.fround(1.337) === 1.337; // false
+
+ +

2150 超出32位浮点,所以返回Infinity

+ +
2 ** 150; // 1.42724769270596e+45
+Math.fround(2 ** 150); // Infinity
+
+ +

如果参数无法转换成数字,或者为 {{jsxref("NaN")}} (NaN),Math.fround() 会返回 NaN

+ +
Math.fround('abc'); // NaN
+Math.fround(NaN); // NaN
+
+ +

在某些精度不高的场合下,可以通过将二个浮点数转换成32位浮点数进行比较,以解决64位浮点数比较结果不正确的问题:

+ +
0.1 + 0.2 == 0.3;    //false
+
+function equal(v1, v2) {
+    return Math.fround(v1) == Math.fround(v2);
+}
+
+equal(0.1 + 0.2, 0.3);   //true
+
+ +

Polyfill

+ +

下面的函数可以模拟这个 API,前提是浏览器必须已经支持 {{jsxref("Float32Array")}}:

+ +
Math.fround = Math.fround || (function (array) {
+  return function(x) {
+    return array[0] = x, array[0];
+  };
+})(new Float32Array(1));
+ +

规范

+ + + + + + + + + + + + +
规范名称规范状态
{{SpecName('ES6', '#sec-math.fround', 'Math.fround')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("38")}}{{CompatGeckoDesktop("26")}}{{CompatNo}}{{CompatOpera("25")}}{{CompatSafari("7.1")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}iOS 8
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/hypot/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/hypot/index.html new file mode 100644 index 0000000000..ab2b81bd7b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/hypot/index.html @@ -0,0 +1,118 @@ +--- +title: Math.hypot() +slug: Web/JavaScript/Reference/Global_Objects/Math/hypot +tags: + - JavaScript + - Math + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/hypot +--- +
{{JSRef}}
+ +

Math.hypot() 函数返回所有参数的平方和的平方根,即:

+ +

Math.hypot(v1,v2,,vn)=i=1nvi2=v12+v22++vn2\mathtt{\operatorname{Math.hypot}(v_1, v_2, \dots, v_n)} = \sqrt{\sum_{i=1}^n v_i^2} = \sqrt{v_1^2 + v_2^2 + \dots + v_n^2}

+ +
{{EmbedInteractiveExample("pages/js/math-hypot.html")}}
+ + + +

语法

+ +
Math.hypot([value1[,value2, ...]]) 
+ +

参数

+ +
+
value1, value2, ...
+
任意个数字。
+
+ +

返回值

+ +

将所提供的参数求平方和后开平方根。如果有参数不能转换为数字,则返回 {{jsxref("NaN")}}。

+ +

描述

+ +

计算直角三角形的斜边,或复数的幅值时可以使用函数 Math.sqrt(v1*v1 + v2*v2) ,其中 v1 和 v2 是三角形的两个直角边或复数的实部和虚部。如果想计算更多维度,那么只需要在后面添加更多的数的平方就可以了,比如 Math.sqrt(v1*v1 + v2*v2 + v3*v3 + v4*v4)

+ +

本函数比 Math.sqrt() 更简单也更快,你只需要调用 Math.hypot(v1, v2) 或 Math.hypot(v1, v2, v3, v4, ...)

+ +

它还避免了幅值过大的问题。 JS 中最大的双精度浮点数是 Number.MAX_VALUE = 1.797...e+308。如果你的数字比约 1e154 大,计算其平方值会返回 Infinity,使你的结果出现问题。比如,Math.sqrt(1e200*1e200 + 1e200*1e200) = Infinity。如果你改用 hypot() 函数,你可以得到正确的答案:Math.hypot(1e200, 1e200) = 1.4142...e+200。在数字非常小的时候同样如此,比如 Math.sqrt(1e-200*1e-200 + 1e-200*1e-200) = 0,但 Math.hypot(1e-200, 1e-200) =1.4142...e-200 则是正确的结果。

+ +

由于 hypotMath 的静态方法,所以应该以 Math.hypot()的方式使用,而不是作为你创建的 Math 对象的属性(Math 不是一个构造函数)。

+ +

如果不传入任何参数, 则返回 +0 .

+ +

如果参数列表中有至少一个参数不能被转换为数字,则返回  {{jsxref("NaN")}}。

+ +

如果只传入一个参数,  Math.hypot(x) 等同于 Math.abs(x).

+ +

示例

+ +

Using Math.hypot()

+ +
Math.hypot(3, 4);        // 5
+Math.hypot(3, 4, 5);     // 7.0710678118654755
+Math.hypot();            // 0
+Math.hypot(NaN);         // NaN
+Math.hypot(3, 4, 'foo'); // NaN, +'foo' => NaN
+Math.hypot(3, 4, '5');   // 7.0710678118654755, +'5' => 5
+Math.hypot(-3);          // 3, the same as Math.abs(-3)
+
+ +

向下兼容

+ +

此函数可以使用如下代码模拟:

+ +
if (!Math.hypot) Math.hypot = function() {
+  var y = 0, i = arguments.length;
+  while (i--) y += arguments[i] * arguments[i];
+  return Math.sqrt(y);
+};
+
+ +

另一种避免结果溢出的实现:

+ +
if (!Math.hypot) Math.hypot = function (x, y) {
+  // https://bugzilla.mozilla.org/show_bug.cgi?id=896264#c28
+  var max = 0;
+  var s = 0;
+  for (var i = 0; i < arguments.length; i += 1) {
+    var arg = Math.abs(Number(arguments[i]));
+    if (arg > max) {
+      s *= (max / arg) * (max / arg);
+      max = arg;
+    }
+    s += arg === 0 && max === 0 ? 0 : (arg / max) * (arg / max);
+  }
+  return max === 1 / 0 ? 1 / 0 : max * Math.sqrt(s);
+};
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-math.hypot', 'Math.hypot')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Math.hypot")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html new file mode 100644 index 0000000000..67da70040d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/imul/index.html @@ -0,0 +1,141 @@ +--- +title: Math.imul() +slug: Web/JavaScript/Reference/Global_Objects/Math/imul +translation_of: Web/JavaScript/Reference/Global_Objects/Math/imul +--- +
{{JSRef("Global_Objects", "Math")}}
+ +
该函数将两个参数分别转换为 32 位整数,相乘后返回 32 位结果,类似 C 语言的 32 位整数相乘。
+ +
+

{{EmbedInteractiveExample("pages/js/math-imul.html")}}

+
+ +

语法

+ +
var product = Math.imul(a, b)
+ +

参数

+ +
+
a
+
被乘数.
+
b
+
乘数.
+
+ +

返回值

+ +

类似 C 语言 32 位整数相乘的结果。

+ +

描述

+ +

Math.imul() 可以进行类似 C 语言的 32 位整数相乘。该特性对于一些项目比如 Emscripten 很有用。因为 imul() 是 Math 的静态方法,所以用法是  Math.imul(),而不是新创建的 Math 对象的方法(Math 不是构造函数)。如果使用 JavaScript 浮点数做为 imul 的参数,会有性能损失。这是因为相乘前 imul 会将浮点数转换为整数,相乘后会将整数重新转换为浮点数,这两步转换的开销是比较大的。imul 存在的原因是在 AsmJS(目前为止唯一一种环境)下它是快速的。AsmJS 使 JIST-optimizers 更容易实现 JavaScript 内部的整数。现代浏览器中,唯一能体现出 imul 性能优越的场景是两个 Number 内部以整数的形式相乘(仅在 AsmJS 下可行)。

+ +

例子

+ +
Math.imul(2, 4) // 8
+Math.imul(-1, 8) // -8
+Math.imul(-2, -2) // 4
+Math.imul(0xffffffff, 5) //-5
+Math.imul(0xfffffffe, 5) //-10
+
+ +

Polyfill

+ +

下面的 JavaScript 代码可以实现该函数:

+ +
if (!Math.imul) Math.imul = function(a, b) {
+  var aHi = (a >>> 16) & 0xffff;
+  var aLo = a & 0xffff;
+  var bHi = (b >>> 16) & 0xffff;
+  var bLo = b & 0xffff;
+  // the shift by 0 fixes the sign on the high part
+  // the final |0 converts the unsigned value into a signed value
+  return ((aLo * bLo) + (((aHi * bLo + aLo * bHi) << 16) >>> 0) | 0);
+};
+ +

然而,下面的实现性能会更好一些。因为运行这段 polyfill 的浏览器很有可能会在内部使用浮点数,而不是整数表示 javascript 的 Number。

+ +
if (!Math.imul) Math.imul = function(opA, opB) {
+  opB |= 0; // ensure that opB is an integer. opA will automatically be coerced.
+  // floating points give us 53 bits of precision to work with plus 1 sign bit
+  // automatically handled for our convienence:
+  // 1. 0x003fffff /*opA & 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001
+  //    0x1fffff7fc00001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/
+  var result = (opA & 0x003fffff) * opB;
+  // 2. We can remove an integer coersion from the statement above because:
+  //    0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001
+  //    0x1fffffff800001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/
+  if (opA & 0xffc00000 /*!== 0*/) result += (opA & 0xffc00000) * opB |0;
+  return result |0;
+};
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-math.imul', 'Math.imul')}}
+ + + + + +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{ CompatGeckoDesktop("20") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureFirefox Mobile (Gecko)AndroidIE MobileOpera MobileSafari Mobile
Basic support{{ CompatGeckoMobile("20") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/index.html new file mode 100644 index 0000000000..924ac82fc4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/index.html @@ -0,0 +1,187 @@ +--- +title: Math +slug: Web/JavaScript/Reference/Global_Objects/Math +tags: + - JavaScript + - Math + - 参考 + - 数学 + - 计算 +translation_of: Web/JavaScript/Reference/Global_Objects/Math +--- +
{{JSRef}}
+ +

Math 是一个内置对象,它拥有一些数学常数属性和数学函数方法。Math 不是一个函数对象。

+ +

Math 用于 {{jsxref("Number")}} 类型。它不支持 {{jsxref("BigInt")}}。

+ +

描述

+ +

与其他全局对象不同的是,Math 不是一个构造器。Math 的所有属性与方法都是静态的。引用圆周率的写法是 Math.PI,调用正余弦函数的写法是 Math.sin(x)x 是要传入的参数。Math 的常量是使用 JavaScript 中的全精度浮点数来定义的。

+ +

属性

+ +
+
{{jsxref("Math.E")}}
+
欧拉常数,也是自然对数的底数,约等于 2.718
+
{{jsxref("Math.LN2")}}
+
2 的自然对数,约等于 0.693
+
{{jsxref("Math.LN10")}}
+
10 的自然对数,约等于 2.303
+
{{jsxref("Math.LOG2E")}}
+
2 为底的 E 的对数,约等于 1.443
+
{{jsxref("Math.LOG10E")}}
+
10 为底的 E 的对数,约等于 0.434
+
{{jsxref("Math.PI")}}
+
圆周率,一个圆的周长和直径之比,约等于 3.14159
+
{{jsxref("Math.SQRT1_2")}}
+
二分之一 ½ 的平方根,同时也是 2 的平方根的倒数 12,约等于 0.707
+
{{jsxref("Math.SQRT2")}}
+
2 的平方根,约等于 1.414
+
+ +

方法

+ +
+

需要注意的是,三角函数 sin()cos()tan()asin()acos()atan()atan2() 返回的值是弧度而非角度。

+ +

若要转换,弧度除以 (Math.PI / 180) 即可转换为角度,同理,角度乘以这个数则能转换为弧度。

+
+ +
+

需要注意的是,很多 Math 函数都有一个精度,而且这个精度在不同实现中也是不相同的。这意味着不同的浏览器会给出不同的结果,甚至,在不同的系统或架构下,相同的 JS 引擎也会给出不同的结果!

+
+ +
+
{{jsxref("Global_Objects/Math/abs", "Math.abs(x)")}}
+
返回一个数的绝对值。
+
{{jsxref("Global_Objects/Math/acos", "Math.acos(x)")}}
+
返回一个数的反余弦值。
+
{{jsxref("Global_Objects/Math/acosh", "Math.acosh(x)")}}
+
返回一个数的反双曲余弦值。
+
{{jsxref("Global_Objects/Math/asin", "Math.asin(x)")}}
+
返回一个数的反正弦值。
+
{{jsxref("Global_Objects/Math/asinh", "Math.asinh(x)")}}
+
返回一个数的反双曲正弦值。
+
{{jsxref("Global_Objects/Math/atan", "Math.atan(x)")}}
+
返回一个数的反正切值。
+
{{jsxref("Global_Objects/Math/atanh", "Math.atanh(x)")}}
+
返回一个数的反双曲正切值。
+
{{jsxref("Global_Objects/Math/atan2", "Math.atan2(y, x)")}}
+
返回 y/x 的反正切值。
+
{{jsxref("Global_Objects/Math/cbrt", "Math.cbrt(x)")}}
+
返回一个数的立方根。
+
{{jsxref("Global_Objects/Math/ceil", "Math.ceil(x)")}}
+
返回大于一个数的最小整数,即一个数向上取整后的值。
+
{{jsxref("Global_Objects/Math/clz32", "Math.clz32(x)")}}
+
返回一个 32 位整数的前导零的数量。
+
{{jsxref("Global_Objects/Math/cos", "Math.cos(x)")}}
+
返回一个数的余弦值。
+
{{jsxref("Global_Objects/Math/cosh", "Math.cosh(x)")}}
+
返回一个数的双曲余弦值。
+
{{jsxref("Global_Objects/Math/exp", "Math.exp(x)")}}
+
返回欧拉常数的参数次方,Ex,其中 x 为参数,E 是欧拉常数(2.718...,自然对数的底数)。
+
{{jsxref("Global_Objects/Math/expm1", "Math.expm1(x)")}}
+
返回 exp(x) - 1 的值。
+
{{jsxref("Global_Objects/Math/floor", "Math.floor(x)")}}
+
返回小于一个数的最大整数,即一个数向下取整后的值。
+
{{jsxref("Global_Objects/Math/fround", "Math.fround(x)")}}
+
返回最接近一个数的单精度浮点型表示。
+
{{jsxref("Global_Objects/Math/hypot", "Math.hypot([x[, y[, …]]])")}}
+
返回其所有参数平方和的平方根。
+
{{jsxref("Global_Objects/Math/imul", "Math.imul(x, y)")}}
+
返回 32 位整数乘法的结果。
+
{{jsxref("Global_Objects/Math/log", "Math.log(x)")}}
+
返回一个数的自然对数(㏒e,即 ㏑)。
+
{{jsxref("Global_Objects/Math/log1p", "Math.log1p(x)")}}
+
返回一个数加 1 的和的自然对数(㏒e,即 ㏑)。
+
{{jsxref("Global_Objects/Math/log10", "Math.log10(x)")}}
+
返回一个数以 10 为底数的对数。
+
{{jsxref("Global_Objects/Math/log2", "Math.log2(x)")}}
+
返回一个数以 2 为底数的对数。
+
{{jsxref("Global_Objects/Math/max", "Math.max([x[, y[, …]]])")}}
+
返回零到多个数值中最大值。
+
{{jsxref("Global_Objects/Math/min", "Math.min([x[, y[, …]]])")}}
+
返回零到多个数值中最小值。
+
{{jsxref("Global_Objects/Math/pow", "Math.pow(x, y)")}}
+
返回一个数的 y 次幂。
+
{{jsxref("Global_Objects/Math/random", "Math.random()")}}
+
返回一个 0 到 1 之间的伪随机数。
+
{{jsxref("Global_Objects/Math/round", "Math.round(x)")}}
+
返回四舍五入后的整数。
+
{{jsxref("Global_Objects/Math/sign", "Math.sign(x)")}}
+
返回一个数的符号,得知一个数是正数、负数还是 0。
+
{{jsxref("Global_Objects/Math/sin", "Math.sin(x)")}}
+
返回一个数的正弦值。
+
{{jsxref("Global_Objects/Math/sinh", "Math.sinh(x)")}}
+
返回一个数的双曲正弦值。
+
{{jsxref("Global_Objects/Math/sqrt", "Math.sqrt(x)")}}
+
返回一个数的平方根。
+
{{jsxref("Global_Objects/Math/tan", "Math.tan(x)")}}
+
返回一个数的正切值。
+
{{jsxref("Global_Objects/Math/tanh", "Math.tanh(x)")}}
+
返回一个数的双曲正切值。
+
Math.toSource()
+
返回字符串 "Math"
+
{{jsxref("Global_Objects/Math/trunc", "Math.trunc(x)")}}
+
返回一个数的整数部分,直接去除其小数点及之后的部分。
+
+ + + +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-math-object', 'Math')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Math")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/ln10/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/ln10/index.html new file mode 100644 index 0000000000..dac9f67466 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/ln10/index.html @@ -0,0 +1,99 @@ +--- +title: Math.LN10 +slug: Web/JavaScript/Reference/Global_Objects/Math/LN10 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/LN10 +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.LN10 属性表示 10 的自然对数,约为 2.302:

+

Math.LN10=ln(10)2.302\mathtt{\mi{Math.LN10}} = \ln(10) \approx 2.302

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

由于 LN10Math 的静态属性,所以应该像这样使用:Math.LN10,而不是作为你创建的 Math 实例的属性(Math 不是构造函数)。

+

示例

+

例子:使用 Math.LN10

+

下面的函数返回 10 的自然对数:

+
function getNatLog10() {
+   return Math.LN10
+}
+
+getNatLog10() // 2.302585092994046
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.1.2', 'Math.LN10')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.ln10', 'Math.LN10')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/ln2/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/ln2/index.html new file mode 100644 index 0000000000..ab79666f23 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/ln2/index.html @@ -0,0 +1,99 @@ +--- +title: Math.LN2 +slug: Web/JavaScript/Reference/Global_Objects/Math/LN2 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/LN2 +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.LN2 属性表示 2 的自然对数,约为 0.693:

+

Math.LN2=ln(2)0.693\mathtt{\mi{Math.LN2}} = \ln(2) \approx 0.693

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

由于 LN2Math 的静态属性,所以应该像这样使用:Math.LN2,而不是作为你创建的 Math 实例的属性(Math 不是构造函数)。

+

示例

+

例子:使用 Math.LN2

+

下面的函数返回 2 的自然对数:

+
function getNatLog2() {
+   return Math.LN2
+}
+
+getNatLog2() // 0.6931471805599453
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.1.3', 'Math.LN2')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.ln2', 'Math.LN2')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/log/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/log/index.html new file mode 100644 index 0000000000..d91a937ec1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/log/index.html @@ -0,0 +1,139 @@ +--- +title: Math.log() +slug: Web/JavaScript/Reference/Global_Objects/Math/log +translation_of: Web/JavaScript/Reference/Global_Objects/Math/log +--- +

{{JSRef("Global_Objects", "Math")}}

+ +

概述

+ +

Math.log() 函数返回一个数的自然对数,即:

+ +

x>0,Math.log(x)=ln(x)=the uniqueysuch thatey=x\forall x > 0, \mathtt{\operatorname{Math.log}(x)} = \ln(x) = \text{the unique} \; y \; \text{such that} \; e^y = x

+ +

语法

+ +
Math.log(x)
+ +

参数

+ +
+
x
+
一个数字.
+
+ +

描述

+ +

如果指定的 number 为负数,则返回值为 NaN

+ +

由于 log 是 Math 的静态方法,所以应该像这样使用:Math.log(),而不是作为你创建的 Math 对象的方法。

+ +

示例

+ +

例子1:使用Math.log

+ +

下面的函数返回指定变量的自然对数:

+ +
Math.log(-1); // NaN, out of range
+Math.log(0); // -Infinity
+Math.log(1); // 0
+Math.log(10); // 2.302585092994046
+ +

例子2: 使用Math.log时基于不同的底数

+ +

下面的函数返回以 x 为底 y 的对数(即logx y):

+ +
function getBaseLog(x, y) {
+    return Math.log(y) / Math.log(x);
+}
+ +

如果你运行 getBaseLog(10, 1000),则会返回2.9999999999999996,非常接近实际答案:3,原因是浮点数精度问题。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.10', 'Math.log')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.log', 'Math.log')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ +

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/log10/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/log10/index.html new file mode 100644 index 0000000000..7819f922e8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/log10/index.html @@ -0,0 +1,113 @@ +--- +title: Math.log10() +slug: Web/JavaScript/Reference/Global_Objects/Math/log10 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/log10 +--- +
+
{{JSRef("Global_Objects", "Math")}}
+
+ +

概述

+ +

Math.log10() 函数返回一个数字以 10 为底的对数.

+ +

语法

+ +
Math.log10(x)
+ +

参数

+ +
+
x
+
任意数字.
+
+ +

描述

+ +

如果传入的参数小于 0, 则返回 NaN.

+ +

示例

+ +
Math.log10(10)   // 1
+Math.log10(100)  // 2
+Math.log10("100")// 2
+Math.log10(1)    // 0
+Math.log10(0)    // -Infinity
+Math.log10(-2)   // NaN
+Math.log10("foo")// NaN
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-math.log10', 'Math.log10')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatGeckoDesktop("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/log10e/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/log10e/index.html new file mode 100644 index 0000000000..3a929935f1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/log10e/index.html @@ -0,0 +1,99 @@ +--- +title: Math.LOG10E +slug: Web/JavaScript/Reference/Global_Objects/Math/LOG10E +translation_of: Web/JavaScript/Reference/Global_Objects/Math/LOG10E +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.LOG10E 属性表示以 10 为底数,e 的对数,约为 0.434:

+

Math.LOG10E=log10(e)0.434\mathtt{\mi{Math.LOG10E}} = \log_10(e) \approx 0.434

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

由于 LOG10EMath 的静态属性,所以应该像这样使用:Math.LOG10E,而不是作为你创建的 Math 实例的属性(Math 不是一个构造函数)。

+

示例

+

例子:使用 Math.LOG10E

+

下面的函数返回以 10为底数,E的对数:

+
function getLog10e() {
+   return Math.LOG10E
+}
+
+getLog10e() // 0.4342944819032518
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.1.5', 'Math.LOG10E')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.log10e', 'Math.LOG10E')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/log1p/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/log1p/index.html new file mode 100644 index 0000000000..2f9b0c64a5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/log1p/index.html @@ -0,0 +1,116 @@ +--- +title: Math.log1p() +slug: Web/JavaScript/Reference/Global_Objects/Math/log1p +translation_of: Web/JavaScript/Reference/Global_Objects/Math/log1p +--- +
+
{{JSRef("Global_Objects", "Math")}}
+
+ +

概述

+ +

Math.log1p() 函数返回一个数字加1后的自然对数 (底为 E), 既log(x+1).

+ +

语法

+ +
Math.log1p(x)
+ +

参数

+ +
+
x
+
任意数字.
+
+ +

描述

+ +

如果参数的值小于 -1, 则返回 NaN.

+ +

函数 y = log(x+1) 的图形是这样的:

+ +

 log(x+1)

+ +

示例

+ +
Math.log1p(Math.E-1)  // 1
+Math.log1p(0)         // 0
+Math.log1p("0")       // 0
+Math.log1p(-1)        // -Infinity
+Math.log1p(-2)        // NaN
+Math.log1p("foo")     // NaN
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-math.log1p', 'Math.log1p')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatGeckoDesktop("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/log2/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/log2/index.html new file mode 100644 index 0000000000..bb048cd49a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/log2/index.html @@ -0,0 +1,113 @@ +--- +title: Math.log2() +slug: Web/JavaScript/Reference/Global_Objects/Math/log2 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/log2 +--- +
+
{{JSRef("Global_Objects", "Math")}}
+
+ +

概述

+ +

Math.log2() 函数返回一个数字以 2 为底的对数.

+ +

语法

+ +
Math.log2(x)
+ +

参数

+ +
+
x
+
任意数字.
+
+ +

描述

+ +

如果传入的参数小于 0, 则返回 NaN.

+ +

示例

+ +
Math.log2(2)     // 1
+Math.log2(1024)  // 10
+Math.log2(1)     // 0
+Math.log2(0)     // -Infinity
+Math.log2(-2)    // NaN
+Math.log2("1024")// 10
+Math.log2("foo") // NaN
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-math.log2', 'Math.log2')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatGeckoDesktop("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/log2e/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/log2e/index.html new file mode 100644 index 0000000000..9c68f4cc57 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/log2e/index.html @@ -0,0 +1,99 @@ +--- +title: Math.LOG2E +slug: Web/JavaScript/Reference/Global_Objects/Math/LOG2E +translation_of: Web/JavaScript/Reference/Global_Objects/Math/LOG2E +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.LOG2E 属性表示以 2 为底数,e 的对数,约为 1.442:

+

Math.LOG2E=log2(e)1.442\mathtt{\mi{Math.LOG2E}} = \log_2(e) \approx 1.442

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

由于 LOG2EMath 的静态属性,所以应该像这样使用:Math.LOG2E,而不是作为你创建的 Math 对象的属性(Math 不是一个构造函数)。

+

示例

+

例子:使用 Math.LOG2E

+

下面的函数返回以 2 为底数,E 的对数:

+
function getLog2e() {
+   return Math.LOG2E
+}
+
+getLog2e() // 1.4426950408889634
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.1.4', 'Math.LOG2E')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.log2e', 'Math.LOG2E')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/max/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/max/index.html new file mode 100644 index 0000000000..593776318e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/max/index.html @@ -0,0 +1,99 @@ +--- +title: Math.max() +slug: Web/JavaScript/Reference/Global_Objects/Math/max +tags: + - JavaScript + - Math +translation_of: Web/JavaScript/Reference/Global_Objects/Math/max +--- +
{{JSRef}}
+ +

Math.max() 函数返回一组数中的最大值。

+ +

{{EmbedInteractiveExample("pages/js/math-max.html")}}

+ +

语法

+ +
Math.max(value1[,value2, ...]) 
+ +

参数

+ +
+
value1, value2, ...
+
一组数值
+
+ +

返回值

+ +

返回给定的一组数字中的最大值。如果给定的参数中至少有一个参数无法被转换成数字,则会返回 {{jsxref("NaN")}}。

+ +

描述

+ +

由于 maxMath 的静态方法,所以应该像这样使用:Math.max(),而不是创建的 Math 实例的方法(Math 不是构造函数)。

+ +

如果没有参数,则结果为 - {{jsxref("Infinity")}}。

+ +

如果有任一参数不能被转换为数值,则结果为 {{jsxref("NaN")}}。

+ +

示例

+ +

使用 Math.max()

+ +
Math.max(10, 20);   //  20
+Math.max(-10, -20); // -10
+Math.max(-10, 20);  //  20
+ +

下面的方法使用 {{jsxref("Global_Objects/Function/apply", "apply")}} 方法寻找一个数值数组中的最大元素。getMaxOfArray([1,2,3]) 等价于 Math.max(1, 2, 3),但是你可以使用 getMaxOfArray ()作用于任意长度的数组上。

+ +
function getMaxOfArray(numArray) {
+    return Math.max.apply(null, numArray);
+}
+
+ +

或者通过使用最新的扩展语句{{jsxref("Operators/Spread_operator", "spread operator")}},获得数组中的最大值变得更容易。

+ +
var arr = [1, 2, 3];
+var max = Math.max(...arr);
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.8.2.11', 'Math.max')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-math.max', 'Math.max')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-math.max', 'Math.max')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Math.max")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/min/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/min/index.html new file mode 100644 index 0000000000..2cc029c6c3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/min/index.html @@ -0,0 +1,155 @@ +--- +title: Math.min() +slug: Web/JavaScript/Reference/Global_Objects/Math/min +tags: + - JavaScript + - Math + - Math.min + - 参考 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/min +--- +
{{JSRef}}
+ +

Math.min() 返回零个或更多个数值的最小值。

+ +

语法

+ +
Math.min([value1[,value2, ...]]) 
+ +

参数

+ +
+
value1, value2, ...
+
一组数值
+
+ +

返回值

+ +

给定数值中最小的数。如果任一参数不能转换为数值,则返回{{jsxref("NaN")}}。

+ +

描述

+ +

由于 minMath 的静态方法,所以应该像这样使用:Math.min(),而不是作为你创建的 Math 实例的方法(Math 不是构造函数)。

+ +

如果没有参数,结果为{{jsxref("Infinity")}}。

+ +

如果有任一参数不能被转换为数值,结果为 {{jsxref("NaN")}}。

+ +

示例

+ +

使用 Math.min()

+ +

下例找出 x 和 y 的最小值,并把它赋值给 z:

+ +
var x = 10, y = -20;
+var z = Math.min(x, y);
+
+ +

使用 Math.min() 裁剪值(Clipping a value)

+ +

Math.min 经常用于裁剪一个值,以便使其总是小于或等于某个边界值。例如:

+ +
var x = f(foo);
+
+if (x > boundary) {
+    x = boundary;
+}
+ +

可以写成:

+ +
var x = Math.min(f(foo), boundary);
+ +
另外,{{jsxref("Math.max()")}} 也可以被用来以相似的方式裁剪一个值。
+ +
 
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0{{Spec2('ES1')}}初始定义。在  JavaScript 1.0 中实现。
{{SpecName('ES5.1', '#sec-15.8.2.12', 'Math.min')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.min', 'Math.min')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-math.min', 'Math.min')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/pi/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/pi/index.html new file mode 100644 index 0000000000..77f373196e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/pi/index.html @@ -0,0 +1,115 @@ +--- +title: Math.PI +slug: Web/JavaScript/Reference/Global_Objects/Math/PI +translation_of: Web/JavaScript/Reference/Global_Objects/Math/PI +--- +
{{JSRef("Global_Objects", "Math")}}
+ +

概述

+ +

Math.PI 表示一个圆的周长与直径的比例,约为 3.14159:

+ +

Math.PI=π3.14159\mathtt{\mi{Math.PI}} = \pi \approx 3.14159

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

由于 PIMath 的静态属性,所以应该像这样使用:Math.PI,而不是作为你创建的 Math 实例的属性(Math 不是构造函数)。

+ +

示例

+ +

使用 Math.PI

+ +

下面的函数使用 Math.PI 计算给定半径的圆周长:

+ +
function calculateCircumference (radius) {
+  return 2 * Math.PI * radius;
+}
+
+calculateCircumference(1);  // 6.283185307179586
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.1.6', 'Math.PI')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.pi', 'Math.PI')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/pow/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/pow/index.html new file mode 100644 index 0000000000..32489252c0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/pow/index.html @@ -0,0 +1,78 @@ +--- +title: Math.pow() +slug: Web/JavaScript/Reference/Global_Objects/Math/pow +translation_of: Web/JavaScript/Reference/Global_Objects/Math/pow +--- +
{{JSRef}}
+ +

Math.pow() 函数返回基数(base)的指数(exponent)次幂,即 baseexponent

+ +

{{EmbedInteractiveExample("pages/js/math-pow.html")}}

+ +

语法

+ +
Math.pow(base, exponent) 
+ +

参数

+ +
+
base
+
基数
+
exponent
+
指数
+
+ +

描述

+ +

由于 pow 是 Math 的静态方法,所以应该像这样使用:Math.pow(),而不是作为你创建的 Math 对象的方法。

+ +

示例

+ +

使用 Math.pow

+ +
function raisePower(x,y) {
+   return Math.pow(x,y)
+}
+ +

如果 x 是 2 ,且 y 是 7,则 raisePower 函数返回 128 (2 的 7 次幂)。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.13', 'Math.pow')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-math.pow', 'Math.pow')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Math.pow")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/random/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/random/index.html new file mode 100644 index 0000000000..46aad728b8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/random/index.html @@ -0,0 +1,94 @@ +--- +title: Math.random() +slug: Web/JavaScript/Reference/Global_Objects/Math/random +tags: + - JavaScript + - Math + - Math.random() + - Method + - 随机数 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/random +--- +
{{JSRef}}
+ +
Math.random() 函数返回一个浮点,  伪随机数在范围从0到小于1,也就是说,从0(包括0)往上,但是不包括1(排除1),然后您可以缩放到所需的范围。实现将初始种子选择到随机数生成算法;它不能被用户选择或重置。
+ +

{{EmbedInteractiveExample("pages/js/math-random.html")}}

+ +
+

Math.random() 不能提供像密码一样安全的随机数字。不要使用它们来处理有关安全的事情。使用Web Crypto API 来代替, 和更精确的{{domxref("RandomSource.getRandomValues()", "window.crypto.getRandomValues()")}} 方法.

+
+ +

语法

+ +
Math.random()
+ +

返回值

+ +

一个浮点型伪随机数字,在0(包括0)和1(不包括)之间。

+ +

示例

+ +

请注意, 由于 JavaScript 中的数字是 IEEE 754 浮点数字,具有最近舍入( round-to-nearest-even)的行为, 因此以下函数的范围 (不包括Math.random() 本身) 并不准确。如果选择了非常大的边界 (253 或更高), 在极罕见的情况下会计算通常-排除(usually-excluded)的上界。(注:round-to-nearest-even采用最近舍入的去偶数舍入的方式,对.5的舍入上,采用取偶数的方式)

+ +

得到一个大于等于0,小于1之间的随机数

+ +
function getRandom() {
+  return Math.random();
+}
+ +

得到一个两数之间的随机数

+ +

这个例子返回了一个在指定值之间的随机数。这个值不小于 min(有可能等于),并且小于(不等于)max

+ +
function getRandomArbitrary(min, max) {
+  return Math.random() * (max - min) + min;
+}
+
+ +

得到一个两数之间的随机整数

+ +

这个例子返回了一个在指定值之间的随机整数。这个值不小于 min (如果 min 不是整数,则不小于 min 的向上取整数),且小于(不等于)max

+ +
function getRandomInt(min, max) {
+  min = Math.ceil(min);
+  max = Math.floor(max);
+  return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
+}
+ +
+

也许很容易想到用 Math.round() 来实现,但是这会导致你的随机数处于一个不均匀的分布,这可能不符合你的需求。

+
+ +

得到一个两数之间的随机整数,包括两个数在内

+ +

上一个例子提到的函数 getRandomInt() 结果范围包含了最小值,但不含最大值。如果你的随机结果需要同时包含最小值和最大值,怎么办呢?  getRandomIntInclusive() 函数可以实现。

+ +
function getRandomIntInclusive(min, max) {
+  min = Math.ceil(min);
+  max = Math.floor(max);
+  return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值 
+}
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-math.random', 'Math.random')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Math.random")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/round/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/round/index.html new file mode 100644 index 0000000000..c1fae674cc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/round/index.html @@ -0,0 +1,356 @@ +--- +title: Math.round() +slug: Web/JavaScript/Reference/Global_Objects/Math/round +tags: + - Math.round() + - 四舍五入 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/round +--- +

{{JSRef}}

+ +

Math.round() 函数返回一个数字四舍五入后最接近的整数。

+ +

语法

+ +
Math.round(x) 
+ +

参数

+ +
+
x
+
一个数值。
+
+

返回值

+ +

给定数字的值四舍五入到最接近的整数。

+
+
+ +

描述

+ +

如果参数的小数部分大于 0.5,则舍入到相邻的绝对值更大的整数。 如果参数的小数部分小于 0.5,则舍入到相邻的绝对值更小的整数。如果参数的小数部分恰好等于0.5,则舍入到相邻的在正无穷(+∞)方向上的整数。注意,与很多其他语言中的round()函数不同,Math.round()并不总是舍入到远离0的方向(尤其是在负数的小数部分恰好等于0.5的情况下)。

+ +

因为 round() 是 Math 的静态方法,你应该直接使用 Math.round(),而不是作为你创建的 Math 对象的一个实例方法来使用(Math没有构造函数)。

+ +

示例

+ +
x = Math.round(20.49);   //20
+x = Math.round(20.5);    //21
+x = Math.round(-20.5);   //-20
+x = Math.round(-20.51);  //-21
+
+ +

小数舍入

+ +
// 闭包
+(function(){
+
+  /**
+   * Decimal adjustment of a number.
+   *
+   * @param {String}  type  The type of adjustment.
+   * @param {Number}  value The number.
+   * @param {Integer} exp   The exponent (the 10 logarithm of the adjustment base).
+   * @returns {Number}      The adjusted value.
+   */
+  function decimalAdjust(type, value, exp) {
+    // If the exp is undefined or zero...
+    if (typeof exp === 'undefined' || +exp === 0) {
+      return Math[type](value);
+    }
+    value = +value;
+    exp = +exp;
+    // If the value is not a number or the exp is not an integer...
+    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
+      return NaN;
+    }
+    // Shift
+    value = value.toString().split('e');
+    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
+    // Shift back
+    value = value.toString().split('e');
+    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
+  }
+
+  // Decimal round
+  if (!Math.round10) {
+    Math.round10 = function(value, exp) {
+      return decimalAdjust('round', value, exp);
+    };
+  }
+  // Decimal floor
+  if (!Math.floor10) {
+    Math.floor10 = function(value, exp) {
+      return decimalAdjust('floor', value, exp);
+    };
+  }
+  // Decimal ceil
+  if (!Math.ceil10) {
+    Math.ceil10 = function(value, exp) {
+      return decimalAdjust('ceil', value, exp);
+    };
+  }
+
+})();
+
+// Round
+Math.round10(55.55, -1); // 55.6
+Math.round10(55.549, -1); // 55.5
+Math.round10(55, 1); // 60
+Math.round10(54.9, 1); // 50
+Math.round10(-55.55, -1); // -55.5
+Math.round10(-55.551, -1); // -55.6
+Math.round10(-55, 1); // -50
+Math.round10(-55.1, 1); // -60
+Math.round10(1.005, -2); // 1.01 -- compare this with Math.round(1.005*100)/100 above
+// Floor
+Math.floor10(55.59, -1); // 55.5
+Math.floor10(59, 1); // 50
+Math.floor10(-55.51, -1); // -55.6
+Math.floor10(-51, 1); // -60
+// Ceil
+Math.ceil10(55.51, -1); // 55.6
+Math.ceil10(51, 1); // 60
+Math.ceil10(-55.59, -1); // -55.5
+Math.ceil10(-59, 1); // -50
+
+ +

或:

+ +
function round(number, precision) {
+    return Math.round(+number + 'e' + precision) / Math.pow(10, precision);
+    //same as:
+    //return Number(Math.round(+number + 'e' + precision) + 'e-' + precision);
+}
+
+round(1.005, 2);    //1.01
+
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.15', 'Math.round')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.round', 'Math.round')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ +

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/sign/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/sign/index.html new file mode 100644 index 0000000000..ca7678c9f0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/sign/index.html @@ -0,0 +1,152 @@ +--- +title: Math.sign() +slug: Web/JavaScript/Reference/Global_Objects/Math/sign +tags: + - JavaScript + - Math + - Math.sign() +translation_of: Web/JavaScript/Reference/Global_Objects/Math/sign +--- +
{{JSRef}}
+ +
 
+ +

Math.sign() 函数返回一个数字的符号, 指示数字是正数,负数还是零。

+ +

语法

+ +
Math.sign(x);
+ +

参数

+ +
+
x
+
任意数字.
+
+ +

描述

+ +

因为 sign Math 的一个静态方法,所以你应该使用 Math.sign() ,而不是作为你创建的一个Math对象的一种方法 (Math不是一个构造函数)。

+ +

而不是作为您创建的Math对象的一种方法(Math不是构造函数)。

+ +

此函数共有5种返回值, 分别是 1, -1, 0, -0, NaN. 代表的各是正数, 负数, 正零, 负零, NaN

+ +

传入该函数的参数会被隐式转换成数字类型。

+ +

示例

+ +

使用Math.sign()

+ +
Math.sign(3);     //  1
+Math.sign(-3);    // -1
+Math.sign("-3");  // -1
+Math.sign(0);     //  0
+Math.sign(-0);    // -0
+Math.sign(NaN);   // NaN
+Math.sign("foo"); // NaN
+Math.sign();      // NaN
+
+ +

Polyfill

+ +
function sign(x) {
+    x = +x ;// convert to a number
+    if (x === 0 || isNaN(x))
+        return x;
+    return x > 0 ? 1 : -1;
+}
+ +

 

+ +
if (!Math.sign) {
+  Math.sign = function(x) {
+    // If x is NaN, the result is NaN.
+    // If x is -0, the result is -0.
+    // If x is +0, the result is +0.
+    // If x is negative and not -0, the result is -1.
+    // If x is positive and not +0, the result is +1.
+    x = +x; // convert to a number
+    if (x === 0 || isNaN(x)) {
+      return Number(x);
+    }
+    return x > 0 ? 1 : -1;
+  };
+}
+ +

 

+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-math.sign', 'Math.sign')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{CompatGeckoDesktop("25")}}{{CompatNo}}25{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/sin/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/sin/index.html new file mode 100644 index 0000000000..989c5af7e5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/sin/index.html @@ -0,0 +1,80 @@ +--- +title: Math.sin() +slug: Web/JavaScript/Reference/Global_Objects/Math/sin +translation_of: Web/JavaScript/Reference/Global_Objects/Math/sin +--- +
{{JSRef("Global_Objects", "Math")}}
+ +

概述

+ +

Math.sin() 函数返回一个数值的正弦值。

+ +

语法

+ +
Math.sin(x)
+ +

参数

+ +
+
x
+
一个数值(以弧度为单位)。
+
+ +

描述

+ +

sin 方法返回一个 -1 到 1 之间的数值,表示给定角度(单位:弧度)的正弦值。

+ +

由于 sinMath 的静态方法,所以应该像这样使用:Math.sin(),而不是作为你创建的 Math 实例的方法。

+ +

示例

+ +

例子:使用 Math.sin

+ +
Math.sin(0);           // 0
+Math.sin(1);           // 0.8414709848078965
+
+Math.sin(Math.PI / 2); // 1
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.16', 'Math.sin')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-math.sin', 'Math.sin')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{ Compat("javascript.builtins.Math.sin") }}

+ +
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/sinh/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/sinh/index.html new file mode 100644 index 0000000000..c9f0d376f9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/sinh/index.html @@ -0,0 +1,123 @@ +--- +title: Math.sinh() +slug: Web/JavaScript/Reference/Global_Objects/Math/sinh +translation_of: Web/JavaScript/Reference/Global_Objects/Math/sinh +--- +
{{JSRef("Global_Objects", "Math")}}
+ +

概述

+ +

 Math.sinh() 函数返回一个数字(单位为角度)的双曲正弦值.

+ +

语法

+ +
Math.sinh(x)
+ +

参数

+ +
+
x
+
任意数字 (单位为度).
+
+ +

描述

+ +

双曲正弦的图像如下:

+ +

+ +

示例

+ +
Math.sinh(0)      // 0
+Math.sinh(1)      // 1.1752011936438014
+Math.sinh("-1")   // -1.1752011936438014
+Math.sinh("foo")  // NaN
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-math.sinh', 'Math.sinh')}}{{Spec2('ES6')}}Initial defintion
+ +

Polyfill

+ +

该函数可以使用 {{jsxref("Math.exp()")}} 函数来实现:

+ +
function sinh(x){
+    return  (Math.exp(x) - Math.exp(-x)) / 2;
+}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatGeckoDesktop("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/sqrt/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/sqrt/index.html new file mode 100644 index 0000000000..badb08802a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/sqrt/index.html @@ -0,0 +1,81 @@ +--- +title: Math.sqrt() +slug: Web/JavaScript/Reference/Global_Objects/Math/sqrt +translation_of: Web/JavaScript/Reference/Global_Objects/Math/sqrt +--- +
{{JSRef}}
+ +

Math.sqrt() 函数返回一个数的平方根,即:

+ +

x0,Math.sqrt(x)=x=the uniquey0such thaty2=x\forall x \geq 0, \mathtt{Math.sqrt(x)} = \sqrt{x} = \text{the unique} \; y \geq 0 \; \text{such that} \; y^2 = x

+ +

{{EmbedInteractiveExample("pages/js/math-sqrt.html")}}

+ +

语法

+ +
Math.sqrt(x) 
+ +

参数

+ +
+
x
+
一个数值
+
+ +

描述

+ +

如果参数 number 为负值,则 sqrt 返回{{jsxref("NaN")}}。

+ +

由于 sqrt 是 Math 的静态方法,所以应该像这样使用:Math.sqrt(),而不是作为你创建的 Math 实例的方法。

+ +

示例

+ +

使用 Math.sqrt

+ +
Math.sqrt(9); // 3
+Math.sqrt(2); // 1.414213562373095
+
+Math.sqrt(1);  // 1
+Math.sqrt(0);  // 0
+Math.sqrt(-1); // NaN
+Math.sqrt(-0); // -0
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.17', 'Math.sqrt')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-math.sqrt', 'Math.sqrt')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Math.sqrt")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/sqrt1_2/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/sqrt1_2/index.html new file mode 100644 index 0000000000..47e0557901 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/sqrt1_2/index.html @@ -0,0 +1,100 @@ +--- +title: Math.SQRT1_2 +slug: Web/JavaScript/Reference/Global_Objects/Math/SQRT1_2 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/SQRT1_2 +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.SQRT1_2 属性表示 1/2 的平方根,约为 0.707:

+

Math.SQRT1_2=12=120.707\mathtt{\mi{Math.SQRT1_2}} = \sqrt{\frac{1}{2}} = \frac{1}{\sqrt{2}} \approx 0.707

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

由于 SQRT1_2Math 对象的静态属性,所以应该像这样使用:Math.SQRT1_2,而不是作为你创建的 Math 实例的属性(Math 不是构造函数)。

+

示例

+

例子:使用 SQRT1_2

+

下面的函数返回 1/2 的平方根:

+
function getRoot1_2() {
+   return Math.SQRT1_2
+}
+
+getRoot1_2() // 0.7071067811865476
+

+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.1.7', 'Math.SQRT1_2')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.sqrt1_2', 'Math.SQRT1_2')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/sqrt2/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/sqrt2/index.html new file mode 100644 index 0000000000..a9eb2ddcd4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/sqrt2/index.html @@ -0,0 +1,96 @@ +--- +title: Math.SQRT2 +slug: Web/JavaScript/Reference/Global_Objects/Math/SQRT2 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/SQRT2 +--- +

{{JSRef("Global_Objects", "Math")}}

+

概述

+

Math.SQRT2 属性表示 2 的平方根,约为 1.414:

+

描述

+

由于 SQRT2 是 Math 的静态属性,所以应该像这样使用:Math.SQRT2,而不是作为你创建的 Math 实例的属性(Math 不是构造函数)。

+

示例

+

例子:使用 Math.SQRT2

+

下面的函数返回 2 的平方根:

+
function getRoot2() {
+   return Math.SQRT2;
+}
+
+getRoot2(); // 1.4142135623730951
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.1.8', 'Math.SQRT2')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.sqrt2', 'Math.SQRT2')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ +

diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/tan/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/tan/index.html new file mode 100644 index 0000000000..9e2464d76e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/tan/index.html @@ -0,0 +1,107 @@ +--- +title: Math.tan() +slug: Web/JavaScript/Reference/Global_Objects/Math/tan +translation_of: Web/JavaScript/Reference/Global_Objects/Math/tan +--- +
+ {{JSRef("Global_Objects", "Math")}}
+

概述

+

Math.tan() 方法返回一个数值的正切值。

+

语法

+
Math.tan(x)
+

参数

+
+
+ x
+
+ 一个数值,表示一个角(单位:弧度)。
+
+

描述

+

tan 方法返回一个数值,表示一个角的正切值。

+

由于 tanMath 的静态方法,所以应该像这样使用 Math.tan(),而不是作为你创建的 Math 实例的方法。

+

示例

+

例子:使用 Math.tan

+

下面的函数返回变量 x 的正切值:

+
function getTan(x) {
+   return Math.tan(x);
+}
+

由于 Math.tan() 函数接受弧度数值,但是通常使用度更方便,下面的函数可以接受以度为单位的数值,将其转为弧度,然后返回其正切值。

+
function getTanDeg(deg) {
+   var rad = deg * Math.PI/180;
+   return Math.tan(rad);
+}
+
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.0StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.8.2.18', 'Math.tan')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-math.tan', 'Math.tan')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

 

diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/tanh/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/tanh/index.html new file mode 100644 index 0000000000..9a3eb0f21d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/tanh/index.html @@ -0,0 +1,85 @@ +--- +title: Math.tanh() +slug: Web/JavaScript/Reference/Global_Objects/Math/tanh +tags: + - ECMAScript6 + - JavaScript + - Math + - Method + - tanh + - 双曲正切 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/tanh +--- +
{{JSRef}}
+ +

Math.tanh() 函数将会返回一个数的双曲正切函数值,公式如下:

+ +

tanhx=sinhxcoshx=ex-e-xex+e-x=e2x-1e2x+1\tanh x = \frac{\sinh x}{\cosh x} = \frac {e^x - e^{-x}} {e^x + e^{-x}} = \frac{e^{2x} - 1}{e^{2x}+1}

+ +
{{EmbedInteractiveExample("pages/js/math-tanh.html")}}
+ +

语法

+ +
Math.tanh(x)
+ +

参数

+ +
+
x
+
待计算的数字。
+
+ +

返回值

+ +

所给数字的双曲正切值。

+ +

描述

+ +

因为 tanh()Math 的静态方法,所以总应该直接调用 Math.tanh() ,而不是创建 Math 对象再调用该方法(Math 不是一个构造函数)。

+ +

示例

+ +

使用 Math.tanh()

+ +
Math.tanh(0);        // 0
+Math.tanh(Infinity); // 1
+Math.tanh(1);        // 0.7615941559557649
+
+ +

向下兼容

+ +

tanh() 可以通过 {{jsxref("Math.exp()")}} 函数实现:

+ +
Math.tanh = Math.tanh || function(x){
+    var a = Math.exp(+x), b = Math.exp(-x);
+    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (a + b);
+}
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-math.tanh', 'Math.tanh')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Math.tanh")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/trunc/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/trunc/index.html new file mode 100644 index 0000000000..f260b85c58 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/trunc/index.html @@ -0,0 +1,116 @@ +--- +title: Math.trunc() +slug: Web/JavaScript/Reference/Global_Objects/Math/trunc +tags: + - ECMAScript 2015 + - JavaScript + - Math + - Method +translation_of: Web/JavaScript/Reference/Global_Objects/Math/trunc +--- +
{{JSRef}}
+ +

Math.trunc() 方法会将数字的小数部分去掉,只保留整数部分。

+ +

语法

+ +
Math.trunc(value)
+ +

参数

+ +
+
value
+
任意数字
+
+ +

返回值

+ +

给定数字的整数部分

+ +

描述

+ +

不像 Math 的其他三个方法: {{jsxref("Math.floor()")}}、{{jsxref("Math.ceil()")}}、{{jsxref("Math.round()")}} ,Math.trunc() 的执行逻辑很简单,仅仅是删除掉数字的小数部分和小数点,不管参数是正数还是负数。

+ +

传入该方法的参数会被隐式转换成数字类型。

+ +

因为 trunc()Math 对象的静态方法,你必须用 Math.trunc() 来使用,而不是调用你创建的 Math 对象的一个实例方法(Math 没有构造函数)

+ +

示例

+ +
Math.trunc(13.37)    // 13
+Math.trunc(42.84)    // 42
+Math.trunc(0.123)    //  0
+Math.trunc(-0.123)   // -0
+Math.trunc("-1.123") // -1
+Math.trunc(NaN)      // NaN
+Math.trunc("foo")    // NaN
+Math.trunc()         // NaN
+ +

Polyfill

+ +
if (!Math.trunc) {
+	Math.trunc = function(v) {
+		v = +v;
+		if (!isFinite(v)) return v;
+
+		return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
+
+		// 返回:
+		//  0        ->  0
+		// -0        -> -0
+		//  0.2      ->  0
+		// -0.2      -> -0
+		//  0.7      ->  0
+		// -0.7      -> -0
+		//  Infinity ->  Infinity
+		// -Infinity -> -Infinity
+		//  NaN      ->  NaN
+		//  null     ->  0
+	};
+}
+
+ +

或:

+ +
if (!Math.trunc) {
+	Math.trunc = function(v) {
+		v = +v;
+		return (v - v % 1) || (!isFinite(v) || v === 0 ? v : v < 0 ? -0 : 0);
+	};
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES2015', '#sec-math.trunc', 'Math.trunc')}}{{Spec2('ES2015')}} 
{{SpecName('ESDraft', '#sec-math.trunc', 'Math.trunc')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Math.trunc")}}

+ +

相关链接

+ + diff --git "a/files/zh-cn/web/javascript/reference/global_objects/math/\345\217\215\345\217\214\346\233\262\344\275\231\345\274\246\345\200\274/index.html" "b/files/zh-cn/web/javascript/reference/global_objects/math/\345\217\215\345\217\214\346\233\262\344\275\231\345\274\246\345\200\274/index.html" new file mode 100644 index 0000000000..7869661836 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/global_objects/math/\345\217\215\345\217\214\346\233\262\344\275\231\345\274\246\345\200\274/index.html" @@ -0,0 +1,91 @@ +--- +title: Math.acosh() +slug: Web/JavaScript/Reference/Global_Objects/Math/反双曲余弦值 +tags: + - JavaScript + - 双曲函数 + - 数学 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/acosh +--- +
{{JSRef}}
+ +

Math.acosh() 函数返回一个数的反双曲余弦值,即:

+ +

x1,Math.acosh(x)=arcosh(x)= the unique y0such thatcosh(y)=x\forall x \geq 1, \mathtt{\operatorname{Math.acosh}(x)} = \operatorname{arcosh}(x) = \text{ 唯一的} \; y \geq 0 \; \text{使得} \; \cosh(y) = x

+ +
{{EmbedInteractiveExample("pages/js/math-acosh.html")}}
+ + + +

语法

+ +
Math.acosh(x)
+ +

参数

+ +
+
x
+
一个数字。
+
+ +

返回值

+ +

返回给定数的反双曲余弦值,如果该数小于 1 则返回 {{jsxref("NaN")}}。

+ +

描述

+ +

因为 acosh() 是 Math 的静态方法,所以总应该直接调用 Math.acosh() ,而不是创建 Math 对象再调用该方法(Math 不是一个构造函数)。

+ +

示例

+ +

使用 Math.acosh()

+ +
Math.acosh(-1);  // NaN
+Math.acosh(0);   // NaN
+Math.acosh(0.5); // NaN
+Math.acosh(1);   // 0
+Math.acosh(2);   // 1.3169578969248166
+
+ +

当参数小于1时, Math.acosh()将返回 {{jsxref("NaN")}}。

+ +

向下兼容

+ +

x1x \geq 1 时,都有 arcosh(x)=ln(x+x2-1)\operatorname {arcosh} (x) = \ln \left(x + \sqrt{x^{2} - 1} \right) ,因此可以使用以下函数实现:

+ +
Math.acosh = Math.acosh || function(x) {
+  return Math.log(x + Math.sqrt(x * x - 1));
+};
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-math.acosh', 'Math.acosh')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Math.acosh")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/nan/index.html b/files/zh-cn/web/javascript/reference/global_objects/nan/index.html new file mode 100644 index 0000000000..777e6a15ce --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/nan/index.html @@ -0,0 +1,68 @@ +--- +title: NaN +slug: Web/JavaScript/Reference/Global_Objects/NaN +tags: + - NaN +translation_of: Web/JavaScript/Reference/Global_Objects/NaN +--- +
{{jsSidebar("Objects")}}
+ +

全局属性 NaN 的值表示不是一个数字(Not-A-Number)。

+ +

{{js_property_attributes(0,0,0)}}

+ +
{{EmbedInteractiveExample("pages/js/globalprops-nan.html")}}
+ +

描述

+ +

NaN 是一个全局对象的属性。

+ +

NaN 属性的初始值就是 NaN,和 {{jsxref("Number.NaN")}} 的值一样。在现代浏览器中(ES5中), NaN 属性是一个不可配置(non-configurable),不可写(non-writable)的属性。但在ES3中,这个属性的值是可以被更改的,但是也应该避免覆盖。

+ +

编码中很少直接使用到 NaN。通常都是在计算失败时,作为 Math 的某个方法的返回值出现的(例如:Math.sqrt(-1))或者尝试将一个字符串解析成数字但失败了的时候(例如:parseInt("blabla"))。

+ +

判断一个值是否是NaN

+ +

NaN如果通过 ==!==== 、以及 !==与其他任何值比较都将不相等 -- 包括与其他 NAN值进行比较。必须使用 {{jsxref("Number.isNaN()")}} 或 {{jsxref("Global_Objects/isNaN", "isNaN()")}} 函数。在执行自比较之中:NaN,也只有NaN,比较之中不等于它自己。

+ +
NaN === NaN;        // false
+Number.NaN === NaN; // false
+isNaN(NaN);         // true
+isNaN(Number.NaN);  // true
+
+function valueIsNaN(v) { return v !== v; }
+valueIsNaN(1);          // false
+valueIsNaN(NaN);        // true
+valueIsNaN(Number.NaN); // true
+ +

但是,请注意isNaN()和Number.isNaN()之间的区别:如果当前值是NaN,或者将其强制转换为数字后将是NaN,则前者将返回true。而后者仅当值当前为NaN时才为true:

+ +
isNaN('hello world');        // true
+Number.isNaN('hello world'); // false
+ +

规范

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-value-properties-of-the-global-object-nan', 'NaN')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.NaN")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/null/index.html b/files/zh-cn/web/javascript/reference/global_objects/null/index.html new file mode 100644 index 0000000000..b2c434ace0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/null/index.html @@ -0,0 +1,93 @@ +--- +title: 'null' +slug: Web/JavaScript/Reference/Global_Objects/null +tags: + - JavaScript + - Literal + - Primitive +translation_of: Web/JavaScript/Reference/Global_Objects/null +--- +
{{jsSidebar("Objects")}}
+ +

值 null 特指对象的值未设置。它是 JavaScript {{Glossary("Primitive", "基本类型")}} 之一,在布尔运算中被认为是falsy

+ +
{{EmbedInteractiveExample("pages/js/globalprops-null.html")}}
+ + + +

语法

+ +
null
+ +

描述

+ +

null 是一个字面量,不像 {{jsxref("Global_Objects/undefined","undefined")}},它不是全局对象的一个属性。null 是表示缺少的标识,指示变量未指向任何对象。把 null 作为尚未创建的对象,也许更好理解。在 API 中,null 常在返回类型应是一个对象,但没有关联的值的地方使用。

+ +
// foo 不存在,它从来没有被定义过或者是初始化过:
+foo;
+"ReferenceError: foo is not defined"
+
+// foo 现在已经是知存在的,但是它没有类型或者是值:
+var foo = null;
+foo;
+null
+ +

null 与 undefined 的不同点:

+ +

当检测 nullundefined 时,注意相等(==)与全等(===)两个操作符的区别 ,前者会执行类型转换:

+ +
typeof null        // "object" (因为一些以前的原因而不是'null')
+typeof undefined   // "undefined"
+null === undefined // false
+null  == undefined // true
+null === null // true
+null == null // true
+!null //true
+isNaN(1 + null) // false
+isNaN(1 + undefined) // true
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-4.3.11', 'null value')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-null-value', 'null value')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-null-value', 'null value')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.null")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/epsilon/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/epsilon/index.html new file mode 100644 index 0000000000..fea6ee1bb8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/epsilon/index.html @@ -0,0 +1,114 @@ +--- +title: Number.EPSILON +slug: Web/JavaScript/Reference/Global_Objects/Number/EPSILON +translation_of: Web/JavaScript/Reference/Global_Objects/Number/EPSILON +--- +
{{JSRef}}
+ +

Number.EPSILON 属性表示 1 与{{jsxref("Number")}}可表示的大于 1 的最小的浮点数之间的差值。

+ +

你不必创建一个 {{jsxref("Number")}} 对象来访问这个静态属性(直接使用 Number.EPSILON)。

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

描述

+ +

EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16,或者 2-52。

+ +

示例

+ +

测试是否相等

+ +
x = 0.2;
+y = 0.3;
+z = 0.1;
+equal = (Math.abs(x - y + z) < Number.EPSILON);
+
+ +

Polyfill

+ +
if (Number.EPSILON === undefined) {
+    Number.EPSILON = Math.pow(2, -52);
+}
+ + + +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-number.epsilon', 'Number.EPSILON')}}{{Spec2('ES6')}}最初定义
{{SpecName('ESDraft', '#sec-number.epsilon', 'Number.EPSILON')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("25.0")}}{{CompatNo}}{{CompatVersionUnknown}}9
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25.0")}}{{CompatNo}}{{CompatNo}}9
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/index.html new file mode 100644 index 0000000000..9e20355b94 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/index.html @@ -0,0 +1,195 @@ +--- +title: Number +slug: Web/JavaScript/Reference/Global_Objects/Number +tags: + - JavaScript + - Number + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Number +--- +
{{JSRef}}
+ +

 JavaScript 的 Number 对象是经过封装的能让你处理数字值的对象。Number 对象由 Number() 构造器创建。

+ +

JavaScript的Number类型为双精度IEEE 754 64位浮点类型。

+ +

最近出了stage3{{jsxref("BigInt")}} 任意精度数字类型,已经进入stage3规范

+ +

语法

+ +
new Number(value);
+var a = new Number('123'); // a === 123 is false
+var b = Number('123'); // b === 123 is true
+a instanceof Number; // is true
+b instanceof Number; // is false
+ +

参数

+ +
+
value
+
被创建对象的数字值。
+
+ +

描述

+ +

Number 对象主要用于:

+ + + +

属性

+ +
+
{{jsxref("Number.EPSILON")}}
+
两个可表示(representable)数之间的最小间隔。
+
{{jsxref("Number.MAX_SAFE_INTEGER")}}
+
JavaScript 中最大的安全整数 (253 - 1)。
+
{{jsxref("Number.MAX_VALUE")}}
+
能表示的最大正数。最小的负数是 -MAX_VALUE
+
{{jsxref("Number.MIN_SAFE_INTEGER")}}
+
JavaScript 中最小的安全整数 (-(253 - 1)).
+
{{jsxref("Number.MIN_VALUE")}}
+
能表示的最小正数即最接近 0 的正数 (实际上不会变成 0)。最大的负数是 -MIN_VALUE
+
{{jsxref("Number.NaN")}}
+
特殊的“非数字”值。
+
{{jsxref("Number.NEGATIVE_INFINITY")}}
+
特殊的负无穷大值,在溢出时返回该值。
+
{{jsxref("Number.POSITIVE_INFINITY")}}
+
特殊的正无穷大值,在溢出时返回该值。
+
{{jsxref("Number.prototype")}}
+
Number 对象上允许的额外属性。
+
+ +

方法

+ +
+
{{jsxref("Number.isNaN()")}}
+
确定传递的值是否是 NaN。
+
{{jsxref("Number.isFinite()")}}
+
确定传递的值类型及本身是否是有限数。
+
{{jsxref("Number.isInteger()")}}
+
确定传递的值类型是“number”,且是整数。
+
{{jsxref("Number.isSafeInteger()")}}
+
确定传递的值是否为安全整数 ( -(253 - 1) 至 253 - 1之间)。
+
{{jsxref("Number.toInteger()")}} {{obsolete_inline}}
+
计算传递的值并将其转换为整数 (或无穷大)。
+
+ +
+
+
{{jsxref("Number.parseFloat()")}}
+
和全局对象 {{jsxref("parseFloat", "parseFloat()")}} 一样。
+
{{jsxref("Number.parseInt()")}}
+
和全局对象 {{jsxref("parseInt", "parseInt()")}} 一样。
+
+
+ +

Number 实例

+ +

所有 Number 实例都继承自 {{jsxref("Number.prototype")}}。被修改的 Number 构造器的原型对象对全部 Number 实例都生效。

+ +

方法

+ +
{{page('/zh-CN/docs/JavaScript/Reference/Global_Objects/Number/prototype', 'Methods')}}
+ +

示例

+ +

使用 Number 对象给数字变量赋值

+ +

下例使用 Number 对象的属性给几个数字变量赋值:

+ +
var biggestNum = Number.MAX_VALUE;
+var smallestNum = Number.MIN_VALUE;
+var infiniteNum = Number.POSITIVE_INFINITY;
+var negInfiniteNum = Number.NEGATIVE_INFINITY;
+var notANum = Number.NaN;
+
+ +

整数类型的范围

+ +

JavaScript 能够准确表示的整数范围在-2^532^53之间(不含两个端点),超过这个范围,无法精确表示这个整数。 (详情请参阅 ECMAScript standard, chapter 6.1.6 The Number Type):

+ +
var biggestInt = Number.MAX_SAFE_INTEGER;
+//9007199254740991
+var smallestInt = Number.MIN_SAFE_INTEGER;
+//-9007199254740991
+ +

在解析序列化的JSON时,如果JSON解析器将它们强制转换为Number类型,那么超出此范围的整数值可能会被破坏。在工作中使用{{jsxref("String")}} 类型代替,是一个可行的解决方案。

+ +

使用 Number 转换 Date 对象

+ +

下例使用 Number 作为函数来转换 Date 对象为数字值:

+ +
var d = new Date("December 17, 1995 03:24:00");
+print(Number(d));
+
+ +

这将输出 "819199440000"。

+ +

转换数字字符串为数字

+ +
Number('123')     // 123
+Number('12.3')    // 12.3
+Number('12.00')   // 12
+Number('123e-1')  // 12.3
+Number('')        // 0
+Number(null)      // 0
+Number('0x11')    // 17
+Number('0b11')    // 3
+Number('0o11')    // 9
+Number('foo')     // NaN
+Number('100a')    // NaN
+Number('-Infinity') //-Infinity
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}初始定义。 实现于 JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.7', 'Number')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-number-objects', 'Number')}}{{Spec2('ES6')}}新增了方法和属性: {{jsxref("Number.EPSILON", "EPSILON")}}, {{jsxref("Number.isFinite", "isFinite")}}, {{jsxref("Number.isInteger", "isInteger")}}, {{jsxref("Number.isNaN", "isNaN")}}, {{jsxref("Number.parseFloat", "parseFloat")}}, {{jsxref("Number.parseInt", "parseInt")}}
{{SpecName('ESDraft', '#sec-number-objects', 'Number')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Number")}}

+
+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/isfinite/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/isfinite/index.html new file mode 100644 index 0000000000..aef163cfb6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/isfinite/index.html @@ -0,0 +1,89 @@ +--- +title: Number.isFinite() +slug: Web/JavaScript/Reference/Global_Objects/Number/isFinite +tags: + - Experimental + - JavaScript + - Method + - Number + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Number/isFinite +--- +
{{JSRef}}
+ +

Number.isFinite() 方法用来检测传入的参数是否是一个有穷数。

+ +

{{EmbedInteractiveExample("pages/js/number-isfinite.html")}}

+ +

语法

+ +
Number.isFinite(value)
+ +

参数

+ +
+
value
+
要被检测有穷性的值。
+
+ +

返回值

+ +

一个 {{jsxref("Boolean", "布尔值")}} 表示给定的值是否是一个有穷数。

+ +

描述

+ +

和全局的 {{jsxref("Global_Objects/isFinite", "isFinite()")}} 函数相比,这个方法不会强制将一个非数值的参数转换成数值,这就意味着,只有数值类型的值,且是有穷的(finite),才返回 true

+ +

Polyfill

+ +
if (Number.isFinite === undefined) Number.isFinite = function(value) {
+    return typeof value === 'number' && isFinite(value);
+}
+ +

示例

+ +
Number.isFinite(Infinity);  // false
+Number.isFinite(NaN);       // false
+Number.isFinite(-Infinity); // false
+
+Number.isFinite(0);         // true
+Number.isFinite(2e64);      // true
+
+Number.isFinite('0');       // false, would've been true with
+                            // global isFinite('0')
+Number.isFinite(null);      // false, would've been true with
+                            // global isFinite(null)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES6', '#sec-number.isfinite', 'Number.isInteger')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-number.isfinite', 'Number.isInteger')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{Compat("javascript.builtins.Number.isFinite")}}
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/isinteger/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/isinteger/index.html new file mode 100644 index 0000000000..742abe51a6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/isinteger/index.html @@ -0,0 +1,92 @@ +--- +title: Number.isInteger() +slug: Web/JavaScript/Reference/Global_Objects/Number/isInteger +tags: + - JavaScript + - Method + - Number + - Reference + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Number/isInteger +--- +
{{JSRef}}
+ +

Number.isInteger() 方法用来判断给定的参数是否为整数。

+ +

{{EmbedInteractiveExample("pages/js/number-isinteger.html")}}

+ +

语法

+ +
Number.isInteger(value)
+ +

参数

+ +
+
value
+
要判断此参数是否为整数
+
+ +

返回值

+ +

判断给定值是否是整数的 {{jsxref("Boolean")}} 值。

+ +

描述

+ +

如果被检测的值是整数,则返回 true,否则返回 false。注意 {{jsxref("Global_Objects/NaN", "NaN")}} 和正负 {{jsxref("Global_Objects/Infinity", "Infinity")}} 不是整数。

+ +

示例

+ +
Number.isInteger(0);         // true
+Number.isInteger(1);         // true
+Number.isInteger(-100000);   // true
+
+Number.isInteger(0.1);       // false
+Number.isInteger(Math.PI);   // false
+
+Number.isInteger(Infinity);  // false
+Number.isInteger(-Infinity); // false
+Number.isInteger("10");      // false
+Number.isInteger(true);      // false
+Number.isInteger(false);     // false
+Number.isInteger([1]);       // false
+ +

Polyfill

+ +
Number.isInteger = Number.isInteger || function(value) {
+    return typeof value === "number" &&
+           isFinite(value) &&
+           Math.floor(value) === value;
+};
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES6', '#sec-number.isinteger', 'Number.isInteger')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-number.isinteger', 'Number.isInteger')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Number.isInteger")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/isnan/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/isnan/index.html new file mode 100644 index 0000000000..19be268773 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/isnan/index.html @@ -0,0 +1,102 @@ +--- +title: Number.isNaN() +slug: Web/JavaScript/Reference/Global_Objects/Number/isNaN +tags: + - ECMAScript 2015 + - JavaScript + - Method + - NaN + - Number + - 数字 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Number/isNaN +--- +
{{JSRef}}
+ +

Number.isNaN() 方法确定传递的值是否为 {{jsxref("NaN")}},并且检查其类型是否为 {{jsxref("Number")}}。它是原来的全局 {{jsxref("isNaN", "isNaN()")}} 的更稳妥的版本。

+ +

{{EmbedInteractiveExample("pages/js/number-isnan.html", "taller")}}

+ +

语法

+ +
Number.isNaN(value)
+ +

参数

+ +
+
value
+
要检测是否为 {{jsxref("Global_Objects/NaN", "NaN")}} 的值。
+
+ +

返回值

+ +

一个{{jsxref("Boolean", "布尔值")}},表示给定的值是否是 {{jsxref("NaN")}}。

+ +

描述

+ +

在 JavaScript 中,NaN 最特殊的地方就是,我们不能使用相等运算符({{jsxref("Operators/Comparison_Operators", "==", "#Equality")}} 和 {{jsxref("Operators/Comparison_Operators", "===", "#Identity")}})来判断一个值是否是 NaN,因为 NaN == NaNNaN === NaN 都会返回 false。因此,必须要有一个判断值是否是 NaN 的方法。

+ +

和全局函数 {{jsxref("Global_Objects/isNaN", "isNaN()")}} 相比,Number.isNaN() 不会自行将参数转换成数字,只有在参数是值为 NaN 的数字时,才会返回 true

+ +

示例

+ +
Number.isNaN(NaN);        // true
+Number.isNaN(Number.NaN); // true
+Number.isNaN(0 / 0)       // true
+
+// 下面这几个如果使用全局的 isNaN() 时,会返回 true。
+Number.isNaN("NaN");      // false,字符串 "NaN" 不会被隐式转换成数字 NaN。
+Number.isNaN(undefined);  // false
+Number.isNaN({});         // false
+Number.isNaN("blabla");   // false
+
+// 下面的都返回 false
+Number.isNaN(true);
+Number.isNaN(null);
+Number.isNaN(37);
+Number.isNaN("37");
+Number.isNaN("37.37");
+Number.isNaN("");
+Number.isNaN(" ");
+ +

Polyfill

+ +
Number.isNaN = Number.isNaN || function(value) {
+    return typeof value === "number" && isNaN(value);
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-number.isnan', 'Number.isnan')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-number.isnan', 'Number.isnan')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +
{{Compat("javascript.builtins.Number.isNaN")}}
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/issafeinteger/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/issafeinteger/index.html new file mode 100644 index 0000000000..e0755f390a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/issafeinteger/index.html @@ -0,0 +1,86 @@ +--- +title: Number.isSafeInteger() +slug: Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger +translation_of: Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger +--- +
{{JSRef}}
+ +

Number.isSafeInteger() 方法用来判断传入的参数值是否是一个“安全整数”(safe integer)。

+ +

一个安全整数是一个符合下面条件的整数:

+ + + +

比如,253 - 1 是一个安全整数,它能被精确表示,在任何 IEEE-754 舍入模式(rounding mode)下,没有其他整数舍入结果为该整数。作为对比,253 就不是一个安全整数,它能够使用 IEEE-754 表示,但是 253 + 1 不能使用 IEEE-754 直接表示,在就近舍入(round-to-nearest)和向零舍入中,会被舍入为 253

+ +

安全整数范围为 -(253 - 1)到 253 - 1 之间的整数,包含 -(253 - 1)和 253 - 1

+ +

语法

+ +
Number.isSafeInteger(testValue)
+ +

参数

+ +
+
testValue
+
需要检测的参数。
+
+ +

返回值

+ +

一个{{jsxref("Boolean", "布尔值")}} 表示给定的值是否是一个安全整数(safe integer)。

+ +

示例

+ +
Number.isSafeInteger(3);                    // true
+Number.isSafeInteger(Math.pow(2, 53))       // false
+Number.isSafeInteger(Math.pow(2, 53) - 1)   // true
+Number.isSafeInteger(NaN);                  // false
+Number.isSafeInteger(Infinity);             // false
+Number.isSafeInteger("3");                  // false
+Number.isSafeInteger(3.1);                  // false
+Number.isSafeInteger(3.0);                  // true
+
+ +

Polyfill

+ +
Number.isSafeInteger = Number.isSafeInteger || function (value) {
+   return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER;
+};
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-number.issafeinteger', 'Number.isSafeInteger')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-number.issafeinteger', 'Number.isSafeInteger')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Number.isSafeInteger")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/max_safe_integer/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/max_safe_integer/index.html new file mode 100644 index 0000000000..2222e5a5ff --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/max_safe_integer/index.html @@ -0,0 +1,105 @@ +--- +title: Number.MAX_SAFE_INTEGER +slug: Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER +translation_of: Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER +--- +
{{JSRef}}
+ +

Number.MAX_SAFE_INTEGER 常量表示在 JavaScript 中最大的安全整数(maxinum safe integer)(253 - 1)。

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

描述

+ +

MAX_SAFE_INTEGER 是一个值为 9007199254740991的常量。因为Javascript的数字存储使用了IEEE 754中规定的双精度浮点数数据类型,而这一数据类型能够安全存储 -(253 - 1) 到 253 - 1 之间的数值(包含边界值)。

+ +

这里安全存储的意思是指能够准确区分两个不相同的值,例如 Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 将得到 true的结果,而这在数学上是错误的,参考{{jsxref("Number.isSafeInteger()")}}获取更多信息.

+ +

由于 MAX_SAFE_INTEGER 是{{jsxref("Number")}}的一个静态属性,所以你不用自己动手为{{jsxref("Number")}}对象创建Number.MAX_SAFE_INTEGER这一属性,就可以直接使用它。

+ +

示例

+ +
Number.MAX_SAFE_INTEGER // 9007199254740991
+Math.pow(2, 53) - 1     // 9007199254740991
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-number.max_safe_integer', 'Number.MAX_SAFE_INTEGER')}}{{Spec2('ES6')}}首次定义
{{SpecName('ESDraft', '#sec-number.max_safe_integer', 'Number.MAX_SAFE_INTEGER')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("34")}}{{CompatGeckoDesktop("31")}}{{CompatNo}}{{CompatVersionUnknown}}9.0.2
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("32")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/max_value/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/max_value/index.html new file mode 100644 index 0000000000..974f0a46e0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/max_value/index.html @@ -0,0 +1,115 @@ +--- +title: Number.MAX_VALUE +slug: Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE +translation_of: Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE +--- +
{{JSRef("Global_Objects", "Number")}}
+ +

概述

+ +

Number.MAX_VALUE 属性表示在 JavaScript 里所能表示的最大数值。

+ +

{{js_property_attributes(0,0,0)}}

+ +

描述

+ +

MAX_VALUE 属性值接近于 1.79E+308。大于 MAX_VALUE 的值代表 "Infinity"。

+ +

因为 MAX_VALUENumber 对象的一个静态属性,所以你应该直接使用Number.MAX_VALUE ,而不是作为一个创建的 Number 实例的属性。

+ +

示例

+ +

例子:使用 MAX_VALUE

+ +

下面的代码求两个数值的乘积。如果结果小于等于 MAX_VALUE,则调用 func1 函数;否则,调用 func2 函数。

+ +
if (num1 * num2 <= Number.MAX_VALUE) {
+   func1();
+} else {
+   func2();
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.3.2', 'Number.MAX_VALUE')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.max_value', 'Number.MAX_VALUE')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/min_safe_integer/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/min_safe_integer/index.html new file mode 100644 index 0000000000..9604955e5b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/min_safe_integer/index.html @@ -0,0 +1,58 @@ +--- +title: Number.MIN_SAFE_INTEGER +slug: Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER +translation_of: Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER +--- +
{{JSRef}}
+ +

Number.MIN_SAFE_INTEGER 代表在 JavaScript中最小的安全的integer型数字 (-(253 - 1)).

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

描述

+ +

MIN_SAFE_INTEGER 的值是-9007199254740991. 形成这个数字的原因是 JavaScript 在 IEEE 754中使用double-precision floating-point format numbers 作为规定。在这个规定中能安全的表示数字的范围在-(253 - 1) 到 253 - 1之间.

+ +

由于MIN_SAFE_INTEGER 是{{jsxref("Number")}}的一个静态属性,你可以直接使用Number.MIN_SAFE_INTEGER, 而不是自己去创建一个{{jsxref("Number")}}的属性。 

+ +

示例

+ +
Number.MIN_SAFE_INTEGER // -9007199254740991
+-(Math.pow(2, 53) - 1)  // -9007199254740991
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-number.min_safe_integer', 'Number.MIN_SAFE_INTEGER')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-number.min_safe_integer', 'Number.MIN_SAFE_INTEGER')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ +
{{CompatibilityTable}}
+ +

{{Compat("javascript.builtins.Number.MIN_SAFE_INTEGER")}}

+ + +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/min_value/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/min_value/index.html new file mode 100644 index 0000000000..0b90f3eb28 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/min_value/index.html @@ -0,0 +1,99 @@ +--- +title: Number.MIN_VALUE +slug: Web/JavaScript/Reference/Global_Objects/Number/MIN_VALUE +translation_of: Web/JavaScript/Reference/Global_Objects/Number/MIN_VALUE +--- +
+ {{JSRef("Global_Objects", "Number")}}
+

概述

+

Number.MIN_VALUE 属性表示在 JavaScript 中所能表示的最小的正值。

+

{{js_property_attributes(0,0,0)}}

+

描述

+

MIN_VALUE 属性是 JavaScript 里最接近 0 的正值,而不是最小的负值。

+

MIN_VALUE 的值约为 5e-324。小于 MIN_VALUE ("underflow values") 的值将会转换为 0。

+

因为 MIN_VALUE 是 Number 的一个静态属性,因此应该直接使用: Number.MIN_VALUE, 而不是作为一个创建的 Number 实例的属性。

+

示例

+

例子:使用 MIN_VALUE

+

下面的代码里两个数值相除。如果结果大于或等于 MIN_VALUE,则调用 func1 函数;否则,调用 func2 函数。

+
if (num1 / num2 >= Number.MIN_VALUE) {
+    func1();
+} else {
+    func2();
+}
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.3.3', 'Number.MIN_VALUE')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.min_value', 'Number.MIN_VALUE')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/nan/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/nan/index.html new file mode 100644 index 0000000000..9921175594 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/nan/index.html @@ -0,0 +1,105 @@ +--- +title: Number.NaN +slug: Web/JavaScript/Reference/Global_Objects/Number/NaN +translation_of: Web/JavaScript/Reference/Global_Objects/Number/NaN +--- +
{{JSRef("Global_Objects", "Number")}}
+ +

概述

+ +

Number.NaN 表示“非数字”(Not-A-Number)。和 {{jsxref("Global_Objects/NaN", "NaN")}} 相同。

+ +

不必创建一个 {{jsxref("Global_Objects/Number", "Number")}} 实例来访问该属性,使用 Number.NaN 来访问该静态属性。

+ +

{{js_property_attributes(0,0,0)}}

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.7.3.4', 'Number.NaN')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.nan', 'Number.NaN')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-number.nan', 'Number.NaN')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/negative_infinity/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/negative_infinity/index.html new file mode 100644 index 0000000000..6649246cf5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/negative_infinity/index.html @@ -0,0 +1,112 @@ +--- +title: Number.NEGATIVE_INFINITY +slug: Web/JavaScript/Reference/Global_Objects/Number/NEGATIVE_INFINITY +translation_of: Web/JavaScript/Reference/Global_Objects/Number/NEGATIVE_INFINITY +--- +
+ {{JSRef("Global_Objects", "Number")}}
+

概述

+

Number.NEGATIVE_INFINITY 属性表示负无穷大。

+

不用创建一个 {{jsxref("Global_Objects/Number", "Number")}} 实例,使用 Number.NEGATIVE_INFINITY 来访问该静态属性。

+

{{js_property_attributes(0,0,0)}}

+

描述

+

Number.NEGATIVE_INFINITY 的值和全局对象的 {{jsxref("Global_Objects/Infinity", "Infinity")}} 属性的负值相同。

+

该值的行为同数学上的无穷大(infinity)有一点儿不同:

+ +

为了成功返回一个有限值,你可能会使用 Number.NEGATIVE_INFINITY 属性来判断是否显示一个条件错误 。然而 {{jsxref("Global_Objects/isFinite", "isFinite")}} 方法更适合这种情况。

+

示例

+

下例中,赋值给变量 smallNumber 一个明显小于 JavaScript 中的最小值的值。当 if 语句执行时,smallNumber 值为 "-Infinity",因此在继续执行代码前,smallNumber 被设为一个更容易管理的值。

+
var smallNumber = (-Number.MAX_VALUE) * 2
+
+if (smallNumber == Number.NEGATIVE_INFINITY) {
+ smallNumber = returnFinite();
+}
+
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.3.5', 'Number.NEGATIVE_INFINITY')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.negative_infinity', 'Number.NEGATIVE_INFINITY')}}{{Spec2('ES6')}} 
+

浏览器规范

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/number/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/number/index.html new file mode 100644 index 0000000000..e539061589 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/number/index.html @@ -0,0 +1,58 @@ +--- +title: Number() constructor +slug: Web/JavaScript/Reference/Global_Objects/Number/Number +translation_of: Web/JavaScript/Reference/Global_Objects/Number/Number +--- +
{{JSRef}}
+ +

Number() 构造函数创建一个 {{jsxref("Number")}} 对象。

+ +

语法

+ +
new Number(value)
+
+ +

参数

+ +
+
value
+
创建的 Number 对象的数值。
+
+ +

例子

+ +

创建 Number 对象

+ +
const a = new Number('123'); // a === 123 is false
+const b = Number('123');     // b === 123 is true
+a instanceof Number;         // is true
+b instanceof Number;         // is false
+ +

规范

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-number-constructor', 'Number constructor')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Number.Number")}}

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/parsefloat/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/parsefloat/index.html new file mode 100644 index 0000000000..f55a3ceba8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/parsefloat/index.html @@ -0,0 +1,109 @@ +--- +title: Number.parseFloat() +slug: Web/JavaScript/Reference/Global_Objects/Number/parseFloat +translation_of: Web/JavaScript/Reference/Global_Objects/Number/parseFloat +--- +
{{JSRef("Global_Objects", "Number")}}
+ +

概述

+ +

Number.parseFloat() 方法可以把一个字符串解析成浮点数。该方法与全局的 {{jsxref("Global_Objects/parseFloat", "parseFloat()")}} 函数相同,并且处于 ECMAScript 6 规范中(用于全局变量的模块化)。

+ +

语法

+ +
Number.parseFloat(string)
+ +

参数

+ +
+
string
+
被解析的字符串。
+
+ +

返回值

+ +
+
给定值被解析成浮点数,如果无法被解析成浮点数,则返回NaN
+
+ +

描述

+ +

请移步全局函数 {{jsxref("Global_Objects/parseFloat", "parseFloat()")}} 页面查看更多的解释和示例。

+ +

规范

+ + + + + + + + + + + + + + +
规范版本规范状态注解
+

{{SpecName('ES6', '#sec-number.parsefloat', 'Number.parseFloat')}}

+
{{Spec2('ES6')}}首次定义
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("25")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("25")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/parseint/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/parseint/index.html new file mode 100644 index 0000000000..56f1d834be --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/parseint/index.html @@ -0,0 +1,82 @@ +--- +title: Number.parseInt() +slug: Web/JavaScript/Reference/Global_Objects/Number/parseInt +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Number +translation_of: Web/JavaScript/Reference/Global_Objects/Number/parseInt +--- +
{{JSRef}}
+ +

概述

+ +

Number.parseInt() 方法依据指定基数 [ 参数 radix 的值],把字符串 [ 参数 string 的值] 解析成整数。

+ +

语法

+ +
Number.parseInt(string[, radix])
+
+ +

参数

+ +

{{page("en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt", "Parameters")}} 

+ +

参数string:要解析的值。 如果此参数不是字符串,则使用ToString抽象操作将其转换为字符串。忽略此参数中的前导空格。
+ 参数radix:一个介于2到36之间的整数,代表字符串的基数(数学数字系统中的基)。小心-这并不是默认为10。

+ +

返回值

+ +

{{page("en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt", "Return value")}}

+ +

从给定字符串中解析的整数。如果基数小于11,且第一个非空白字符不能转换为数字,则返回NaN。

+ +

描述

+ +

这个方法和全局的 {{jsxref("parseInt", "parseInt()")}} 函数具有一样的函数功能:

+ +
Number.parseInt === parseInt; // true
+ +

ECMAScript 2015添加了这部分 (其目的是对全局变量进行模块化). 请另见 {{jsxref("parseInt", "parseInt()")}} 获取更多详情和示例.

+ +

Polyfill

+ +
if (Number.parseInt === undefined) {
+    Number.parseInt = window.parseInt;
+}
+ +

说明

+ + + + + + + + + + + + + + + + + + + +
说明状态评论
{{SpecName('ES2015', '#sec-number.parseint', 'Number.parseInt')}}{{Spec2('ES2015')}}初始定义.
{{SpecName('ESDraft', '#sec-number.parseint', 'Number.parseInt')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

+ +

{{Compat("javascript.builtins.Number.parseInt")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/positive_infinity/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/positive_infinity/index.html new file mode 100644 index 0000000000..4207e72e5a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/positive_infinity/index.html @@ -0,0 +1,130 @@ +--- +title: Number.POSITIVE_INFINITY +slug: Web/JavaScript/Reference/Global_Objects/Number/POSITIVE_INFINITY +translation_of: Web/JavaScript/Reference/Global_Objects/Number/POSITIVE_INFINITY +--- +
{{JSRef("Global_Objects", "Number")}}
+ +

概述

+ +

Number.POSITIVE_INFINITY 属性表示正无穷大。

+ +

不必创建一个 {{jsxref("Global_Objects/Number", "Number")}} 实例,可使用 Number.POSITIVE_INFINITY 来访问该静态属性。

+ +

{{js_property_attributes(0,0,0)}}

+ +

描述

+ +

Number.POSITIVE_INFINITY 的值同全局对象 {{jsxref("Global_Objects/Infinity", "Infinity")}} 属性的值相同。

+ +

该值的表现同数学上的无穷大有点儿不同:

+ + + +

You might use the Number.POSITIVE_INFINITY property to indicate an error condition that returns a finite number in case of success. Note, however, that {{jsxref("Global_Objects/isFinite", "isFinite")}} would be more appropriate in such a case.

+ +

示例

+ +

下例中,赋值给变量 bigNumber 一个大于 JavaScript 中最大值的值。当 if 语句执行时,变量 bigNumber 值为 "Infinity", 因此在继续执行代码前,为变量 bigNumber 设置一个容易管理的值。

+ +
var bigNumber = Number.MAX_VALUE * 2
+if (bigNumber == Number.POSITIVE_INFINITY) {
+ bigNumber = returnFinite();
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.3.6', 'Number.POSITIVE_INFINITY')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.positive_infinity', 'Number.POSITIVE_INFINITY')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/prototype/index.html new file mode 100644 index 0000000000..578011f564 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/prototype/index.html @@ -0,0 +1,131 @@ +--- +title: Number.prototype +slug: Web/JavaScript/Reference/Global_Objects/Number/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Number +--- +
+ {{JSRef("Global_Objects", "Number")}}
+

概述

+

Number.prototype 属性表示 {{jsxref("Global_Objects/Number", "Number")}} 构造函数的原型。

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

所有 Number 实例都继承自 Number.prototype。修改 {{jsxref("Global_Objects/Number", "Number")}} 构造函数的原型对象会影响到所有 Number 实例。.

+

属性

+
+
+ constructor
+
+ 返回创建该实例对象的构造函数。默认为 {{jsxref("Global_Objects/Number", "Number")}} 对象。
+
+
+ {{ jsOverrides("Object", "properties", "constructor") }}
+

方法

+
+
+ {{jsxref("Number.prototype.toExponential()")}}
+
+ 返回一个使用指数表示法表示的该数值的字符串表示。
+
+ {{jsxref("Number.prototype.toFixed()")}}
+
+ 返回一个使用定点表示法表示的该数值的字符串表示。
+
+ {{jsxref("Number.prototype.toLocaleString()")}}
+
+ 返回一个与语言相关的该数值对象的字符串表示。覆盖了{{jsxref("Object.prototype.toLocaleString()")}} 方法。
+
+ {{jsxref("Number.prototype.toPrecision()")}}
+
+ 使用定点表示法或指数表示法来表示的指定显示位数的该数值对象的字符串表示。
+
+ {{jsxref("Number.prototype.toSource()")}} {{ Non-standard_inline() }}
+
+ Returns an object literal representing the specified Number object; you can use this value to create a new object. Overrides the {{jsxref("Object.prototype.toSource()")}} method.
+
+ {{jsxref("Number.prototype.toString()")}}
+
+ 返回一个表示该数值对象的字符串。覆盖了 {{jsxref("Object.prototype.toString()")}} 方法。
+
+ {{jsxref("Number.prototype.valueOf()")}}
+
+ 返回该数值对象的原始值。覆盖了 {{jsxref("Object.prototype.valueOf()")}} 方法。
+
+
+ {{ jsOverrides("Object", "methods", "toExponential", "toFixed", "toLocaleString", "toPrecision", "toSource", "toString", "valueOf") }}
+
+  
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.4', 'Number')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-the-number-prototype-object', 'Number')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

 

diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/toexponential/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/toexponential/index.html new file mode 100644 index 0000000000..a19013e4c4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/toexponential/index.html @@ -0,0 +1,142 @@ +--- +title: Number.prototype.toExponential() +slug: Web/JavaScript/Reference/Global_Objects/Number/toExponential +translation_of: Web/JavaScript/Reference/Global_Objects/Number/toExponential +--- +
{{JSRef("Global_Objects", "Number")}}
+ +

概述

+ +

toExponential() 方法以指数表示法返回该数值字符串表示形式。

+ +

语法

+ +
numObj.toExponential(fractionDigits)
+ +

参数

+ +
+
fractionDigits
+
可选。一个整数,用来指定小数点后有几位数字。默认情况下用尽可能多的位数来显示数字。
+
+ +

返回值

+ +

一个用幂的形式 (科学记数法) 来表示{{jsxref("Number")}} 对象的字符串。小数点后以fractionDigits 提供的值来四舍五入。如果 fractionDigits 参数被忽略了,小数点后的将尽可能用最多的位数来表示该数值。

+ +

对数值字面量使用 toExponential() 方法,且该数值没有小数点和指数时,应该在该数值与该方法之间隔开一个空格,以避免点号被解释为一个小数点。也可以使用两个点号调用该方法。

+ +

如果一个数值的小数位数多余 fractionDigits 参数所提供的,则该数值将会在 fractionDigits 指定的小数位数处四舍五入。可以查看 {{jsxref("Number.toFixed", "toFixed()")}} 方法描述中关于四舍五入的讨论,同样应用于 toExponential() 方法。

+ +

异常

+ +
+
{{jsxref("Global_Objects/RangeError", "RangeError")}}
+
如果 fractionDigits 太小或太大将会抛出该错误。介于 0 和 20(包括20)之间的值不会引起 RangeError 。 执行环境也可以支持更大或更小范围。
+
+ +
+
{{jsxref("Global_Objects/TypeError", "TypeError")}}
+
如果该方法在一个非数值类型对象上调用。
+
+ +

示例

+ +
var numObj = 77.1234;
+
+alert("numObj.toExponential() is " + numObj.toExponential()); //输出 7.71234e+1
+
+alert("numObj.toExponential(4) is " + numObj.toExponential(4)); //输出 7.7123e+1
+
+alert("numObj.toExponential(2) is " + numObj.toExponential(2)); //输出 7.71e+1
+
+alert("77.1234.toExponential() is " + 77.1234.toExponential()); //输出 7.71234e+1
+
+alert("77 .toExponential() is " + 77 .toExponential()); //输出 7.7e+1
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
ECMAScript 3rd Edition. Implemented in JavaScript 1.5StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.4.6', 'Number.prototype.toExponential')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.prototype.toexponential', 'Number.prototype.toExponential')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/tofixed/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/tofixed/index.html new file mode 100644 index 0000000000..03864f8c9e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/tofixed/index.html @@ -0,0 +1,115 @@ +--- +title: Number.prototype.toFixed() +slug: Web/JavaScript/Reference/Global_Objects/Number/toFixed +translation_of: Web/JavaScript/Reference/Global_Objects/Number/toFixed +--- +
{{JSRef}}
+ +

toFixed() 方法使用定点表示法来格式化一个数值。

+ +
{{EmbedInteractiveExample("pages/js/number-tofixed.html")}}
+ +

语法

+ +
numObj.toFixed(digits)
+ +

参数

+ +
+
digits
+
小数点后数字的个数;介于 0 到 20 (包括)之间,实现环境可能支持更大范围。如果忽略该参数,则默认为 0。
+
+ +

返回值

+ +

使用定点表示法表示给定数字的字符串。

+ +

抛出异常

+ +
+
{{jsxref("RangeError")}}
+
如果 digits 参数太小或太大。0 到 20(包括)之间的值不会引起 {{jsxref("RangeError")}}。实现环境(implementations)也可以支持更大或更小的值。
+
+ +
+
{{jsxref("TypeError")}}
+
如果该方法在一个非{{jsxref( "Number")}}类型的对象上调用。
+
+ +

描述

+ +

一个数值的字符串表现形式,不使用指数记数法,而是在小数点后有 digits(注:digits具体值取决于传入参数)位数字。该数值在必要时进行四舍五入,另外在必要时会用 0 来填充小数部分,以便小数部分有指定的位数。 如果数值大于 1e+21,该方法会简单调用 {{jsxref("Number.prototype.toString()")}}并返回一个指数记数法格式的字符串。

+ +
+

Warning: 浮点数不能精确地用二进制表示所有小数。这可能会导致意外的结果,例如 0.1 + 0.2 === 0.3 返回 false .

+
+ +

示例

+ +

使用 toFixed

+ +
var numObj = 12345.6789;
+
+numObj.toFixed();         // 返回 "12346":进行四舍六入五看情况,不包括小数部分
+numObj.toFixed(1);        // 返回 "12345.7":进行四舍六入五看情况
+
+numObj.toFixed(6);        // 返回 "12345.678900":用0填充
+
+(1.23e+20).toFixed(2);    // 返回 "123000000000000000000.00"
+
+(1.23e-10).toFixed(2);    // 返回 "0.00"
+
+2.34.toFixed(1);          // 返回 "2.3"
+
+2.35.toFixed(1)           // 返回 '2.4'. Note it rounds up
+
+2.55.toFixed(1)           // 返回 '2.5'. Note it rounds down - see warning above
+
+-2.34.toFixed(1);         // 返回 -2.3 (由于操作符优先级,负数不会返回字符串)
+
+(-2.34).toFixed(1);       // 返回 "-2.3" (若用括号提高优先级,则返回字符串)
+
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.5.
{{SpecName('ES5.1', '#sec-15.7.4.5', 'Number.prototype.toFixed')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-number.prototype.tofixed', 'Number.prototype.toFixed')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Number.toFixed")}}

+ +

相关链接

+ + + +
+
+
diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/tointeger/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/tointeger/index.html new file mode 100644 index 0000000000..24abe2125e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/tointeger/index.html @@ -0,0 +1,97 @@ +--- +title: Number.toInteger() +slug: Web/JavaScript/Reference/Global_Objects/Number/toInteger +translation_of: Archive/Web/JavaScript/Number.toInteger +--- +
{{JSRef("Global_Objects", "Number")}} {{obsolete_header("33")}} {{non-standard_header}}
+ +

概览

+ +

Number.toInteger() 用来将参数转换成整数,但该方法的实现已被移除.

+ +

如果参数是 {{jsxref("Global_Objects/NaN", "NaN")}}, {{jsxref("Global_Objects/null", "null")}} 或 {{jsxref("Global_Objects/undefined", "undefined")}}, 会返回0 . 如果参数值是true返回1,false的话返回0.

+ +

语法

+ +
Number.toInteger(number)
+ +

参数

+ +
+
number
+
将被转换成整数的参数.
+
+ +

示例

+ +

例子: 使用 toInteger()方法

+ +
Number.toInteger(0.1);     // 0
+Number.toInteger(1);       // 1
+Number.toInteger(Math.PI); // 3
+Number.toInteger(null);    // 0
+
+ +

Specifications

+ + + +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}Firefox 16 to 32{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}Firefox 16 to 32{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/tolocalestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/tolocalestring/index.html new file mode 100644 index 0000000000..e907f810c9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/tolocalestring/index.html @@ -0,0 +1,165 @@ +--- +title: Number.prototype.toLocaleString() +slug: Web/JavaScript/Reference/Global_Objects/Number/toLocaleString +tags: + - JavaScript + - 原型 + - 国际化 + - 数字 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Number/toLocaleString +--- +
{{JSRef("Global_Objects", "Number")}}
+ +

toLocaleString() 方法返回这个数字在特定语言环境下的表示字符串。

+ +

新的 localesoptions 参数让应用程序可以指定要进行格式转换的语言,并且定制函数的行为。在旧的实现中,会忽略 localesoptions 参数,使用的语言环境和返回的字符串的形式完全取决于实现方式。

+ +

语法

+ +
numObj.toLocaleString([locales [, options]])
+ +

参数

+ +

查阅浏览器兼容性部分,了解哪些浏览器支持 localesoptions 参数,通过示例: 检查 localesoptions 参数的支持了解特征检测。

+ +
+

注意: ECMAScript 国际化 API,在 Firefox 29 中得以实施,增加了 locales 参数的 Number.toLocaleString 方法。如果参数为 undefined,此方法返回本地操作系统指定的位数,而 Firefox 的早期版本中返回阿拉伯语数字。这一变化已被报告为向后影响的兼容性问题并可能会被尽快修复。({{ bug(999003) }})

+
+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat', '参数')}}
+ +

返回值

+ +

返回一个语言环境下的表示字符串。

+ +

示例

+ +

使用 toLocaleString

+ +

在没有指定区域的基本使用时,返回使用默认的语言环境和默认选项格式化的字符串。

+ +
var number = 3500;
+
+console.log(number.toLocaleString()); // Displays "3,500" if in U.S. English locale
+
+ +

检查 localesoptions 参数的支持

+ +

localesoptions 参数目前还不是所有浏览器都支持的。在 ES5.1 和更新的实现中检查支持情况,可以依靠使用非法参数时规定抛出的 {{jsxref("Global_Objects/RangeError", "RangeError")}} 异常:

+ +
function toLocaleStringSupportsLocales() {
+  var number = 0;
+  try {
+    number.toLocaleString('i');
+  } catch (e) {
+    return e​.name === 'RangeError';
+  }
+  return false;
+}
+
+ +

早于 ES5.1 的实现中,如果带参数调用 toLocaleString 并不会抛出范围异常。

+ +

在所有宿主环境下,包括那些支持比 ed 5.1 还早的 ECMA-262 的环境,都能有效检测的方法是直接检测 ECMA-402 中的其它特性,它指定 Number.prototype.toLocaleString 需要支持地区选项:

+ +
function toLocaleStringSupportsOptions() {
+  return !!(typeof Intl == 'object' && Intl && typeof Intl.NumberFormat == 'function');
+}
+
+ +

它测试全局的 Intl 对象,检测它不是 null 并且有 NumberFormat 的方法。

+ +

使用 locales

+ +

这个示例展示了不同地区数字格式的差异。为了设置你的应用程序界面下使用的语言格式,请确保使用 locales 参数指定了使用的语言(可能还有一些备用语言):

+ +
var number = 123456.789;
+
+// 德国使用逗号作为小数分隔符,分位周期为千位
+console.log(number.toLocaleString('de-DE'));
+// → 123.456,789
+
+// 在大多数阿拉伯语国家使用阿拉伯语数字
+console.log(number.toLocaleString('ar-EG'));
+// → ١٢٣٤٥٦٫٧٨٩
+
+// 印度使用千位/拉克(十万)/克若尔(千万)分隔
+console.log(number.toLocaleString('en-IN'));
+// → 1,23,456.789
+
+// nu 扩展字段要求编号系统,e.g. 中文十进制
+console.log(number.toLocaleString('zh-Hans-CN-u-nu-hanidec'));
+// → 一二三,四五六.七八九
+
+// 当请求不支持的语言时,例如巴厘语,加入一个备用语言,比如印尼语
+console.log(number.toLocaleString(['ban', 'id']));
+// → 123.456,789
+
+ +

使用 options

+ +

通过 toLocaleString 返回的结果可以通过 options 参数进行定制:

+ +
var number = 123456.789;
+
+// 要求货币格式
+console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
+// → 123.456,79 €
+
+// 日元不使用小数位
+console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
+// → ¥123,457
+
+// 限制三位有效数字
+console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
+// → 1,23,000
+
+ +

性能

+ +

当格式化大量数字时,最好建立一个 {{jsxref("Global_Objects/NumberFormat", "NumberFormat")}} 对象并且使用它提供的 {{jsxref("NumberFormat.format")}} 方法。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注解
ECMAScript 3rd Edition. Implemented in JavaScript 1.5StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.4.3', 'Number.prototype.toLocaleString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.prototype.tolocalestring', 'Number.prototype.toLocaleString')}}{{Spec2('ES6')}} 
ECMAScript Internationalization API Specification, 1st Edition (ECMA-402)Standard 
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Number.toLocaleString")}}

+ +
 
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/toprecision/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/toprecision/index.html new file mode 100644 index 0000000000..daa0fa0bc8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/toprecision/index.html @@ -0,0 +1,133 @@ +--- +title: Number.prototype.toPrecision() +slug: Web/JavaScript/Reference/Global_Objects/Number/toPrecision +translation_of: Web/JavaScript/Reference/Global_Objects/Number/toPrecision +--- +
{{JSRef("Global_Objects", "Number")}}
+ +

概述

+ +

toPrecision() 方法以指定的精度返回该数值对象的字符串表示。

+ +

语法

+ +
numObj.toPrecision(precision)
+ +

参数

+ +
+
precision
+
可选。一个用来指定有效数个数的整数。
+
+ +

返回值

+ +

以定点表示法或指数表示法表示的一个数值对象的字符串表示,四舍五入到 precision 参数指定的显示数字位数。查看 {{jsxref("Number.prototype.toFixed()")}} 方法关于四舍五入的讨论,同样应用于 toPrecision 方法。

+ +

如果忽略 precision 参数,则该方法表现类似于 {{jsxref("Number.prototype.toString()")}}。如果该参数是一个非整数值,将会向下舍入到最接近的整数。

+ +

异常

+ +
+
{{jsxref("Global_Objects/RangeError", "RangeError")}}
+
如果 precison 参数不在 1 和 100 (包括)之间,将会抛出一个 RangeError 。执行环境也可以支持更大或更小的范围。ECMA-262 只需要最多 21 位显示数字。
+
+ +

示例

+ +
var numObj = 5.123456;
+console.log("numObj.toPrecision()  is " + numObj.toPrecision());  //输出 5.123456
+console.log("numObj.toPrecision(5) is " + numObj.toPrecision(5)); //输出 5.1235
+console.log("numObj.toPrecision(2) is " + numObj.toPrecision(2)); //输出 5.1
+console.log("numObj.toPrecision(1) is " + numObj.toPrecision(1)); //输出 5
+
+// 注意:在某些情况下会以指数表示法返回
+console.log((1234.5).toPrecision(2)); // "1.2e+3"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范规范状态注解
ECMAScript 3rd Edition. Implemented in JavaScript 1.5StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.4.7', 'Number.prototype.toPrecision')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.prototype.toprecision', 'Number.prototype.toPrecision')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/tosource/index.html new file mode 100644 index 0000000000..3ed14e1397 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/tosource/index.html @@ -0,0 +1,80 @@ +--- +title: Number.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/Number/toSource +translation_of: Web/JavaScript/Reference/Global_Objects/Number/toSource +--- +
+ {{JSRef("Global_Objects", "Number")}} {{ Non-standard_header() }}
+

概述

+

toSource() 方法返回该对象源码的字符串表示。

+

语法

+
numObj.toSource();
+Number.toSource();
+
+

参数

+

+

描述

+

toSource() 方法返回下列值:

+ + +
function Number() { [native code] }
+ +

该方法通常被 JavaScript 内部调用,而不是在代码中显示调用。

+

规范

+

不是任何标准的一部分。在 JavaScript 1.3 被实现。

+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/tostring/index.html new file mode 100644 index 0000000000..30fdc17406 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/tostring/index.html @@ -0,0 +1,149 @@ +--- +title: Number.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/Number/toString +tags: + - Bug + - Number.prototype.toString() + - Tips +translation_of: Web/JavaScript/Reference/Global_Objects/Number/toString +--- +

{{JSRef}}

+ +

toString() 方法返回指定 {{jsxref("Number")}} 对象的字符串表示形式。

+ +

语法

+ +
numObj.toString([radix])
+
+ +

参数

+ +
+
radix
+
指定要用于数字到字符串的转换的基数(从2到36)。如果未指定 radix 参数,则默认值为 10。
+
+ +

异常信息

+ +
+
{{jsxref("RangeError")}}
+
+

如果 toString() 的 radix 参数不在 2 到 36 之间,将会抛出一个 {{jsxref("RangeError")}}。

+
+
+ +

描述

+ +

{{jsxref("Number")}} 对象覆盖了 {{jsxref("Object")}} 对象上的 toString() 方法,它不是继承的 {{jsxref("Object.prototype.toString()")}}。对于 {{jsxref( "Number")}} 对象,toString() 方法以指定的基数返回该对象的字符串表示。

+ +

如果转换的基数大于10,则会使用字母来表示大于9的数字,比如基数为16的情况,则使用a到f的字母来表示10到15。

+ +

如果基数没有指定,则使用 10。

+ +

如果对象是负数,则会保留负号。即使radix是2时也是如此:返回的字符串包含一个负号(-)前缀和正数的二进制表示,不是 数值的二进制补码。

+ +

进行数字到字符串的转换时,建议用小括号将要转换的目标括起来,防止出错。

+ +

例子

+ +
var count = 10;
+
+console.log(count.toString());    // 输出 '10'
+console.log((17).toString());     // 输出 '17'
+console.log((17.2).toString());   // 输出 '17.2'
+
+var x = 6;
+
+console.log(x.toString(2));       // 输出 '110'
+console.log((254).toString(16));  // 输出 'fe'
+
+console.log((-10).toString(2));   // 输出 '-1010'
+console.log((-0xff).toString(2)); // 输出 '-11111111'
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.7.4.2', 'Number.prototype.tostring')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.prototype.tostring', 'Number.prototype.tostring')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/valueof/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/valueof/index.html new file mode 100644 index 0000000000..81168e6ea0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/number/valueof/index.html @@ -0,0 +1,122 @@ +--- +title: Number.prototype.valueOf() +slug: Web/JavaScript/Reference/Global_Objects/Number/valueOf +tags: + - JavaScript + - Method + - Number + - valueOf() +translation_of: Web/JavaScript/Reference/Global_Objects/Number/valueOf +--- +
{{JSRef("Global_Objects", "Number")}}
+ +

概述

+ +

valueOf() 方法返回一个被 {{jsxref("Global_Objects/Number", "Number")}} 对象包装的原始值。

+ +

语法

+ +
numObj.valueOf()
+ +

返回值

+ +

表示指定 {{jsxref("Number")}} 对象的原始值的数字

+ +

描述

+ +

该方法通常是由 JavaScript 引擎在内部隐式调用的,而不是由用户在代码中显式调用的。

+ +

示例

+ +
var numObj = new Number(10);
+console.log(typeof numObj); // object
+
+var num = numObj.valueOf();
+console.log(num);           // 10
+console.log(typeof num);    // number
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
ECMAScript 1st Edition.Standard 
{{SpecName('ES5.1', '#sec-15.7.4.4', 'Number.prototype.valueOf')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-number.prototype.valueof', 'Number.prototype.valueOf')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/__definegetter__/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/__definegetter__/index.html new file mode 100644 index 0000000000..28773a6bc8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/__definegetter__/index.html @@ -0,0 +1,107 @@ +--- +title: Object.prototype.__defineGetter__() +slug: Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__ +translation_of: Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__ +--- +
+ {{JSRef("Global_Objects", "Object")}} {{non-standard_header}} {{deprecated_header}}
+

概述

+

__defineGetter__ 方法可以将一个函数绑定在当前对象的指定属性上,当那个属性的值被读取时,你所绑定的函数就会被调用。

+

语法

+
obj.__defineGetter__(prop, func)
+

参数

+
+
+ prop
+
+ 一个字符串,表示指定的属性名。
+
+ func
+
+ 一个函数,当 prop 属性的值被读取时自动被调用。
+
+

描述

+

__defineGetter__ 方法可以为一个已经存在的对象设置(新建或修改)访问器属性,而 {{jsxref("Operators/get", "对象字面量中的 get 语法", "", 1)}} 只能在新建一个对象时使用。

+

示例

+
// 请注意,该方法是非标准的:
+
+var o = {};
+o.__defineGetter__('gimmeFive', function() { return 5; });
+console.log(o.gimmeFive); // 5
+
+
+// 请尽可能使用下面的两种推荐方式来代替:
+
+// 1. 在对象字面量中使用 get 语法
+var o = { get gimmeFive() { return 5; } };
+console.log(o.gimmeFive); // 5
+
+// 2. 使用 Object.defineProperty 方法
+var o = {};
+Object.defineProperty(o, 'gimmeFive', {
+  get: function() {
+    return 5;
+  }
+});
+console.log(o.gimmeFive); // 5
+
+

规范

+

不属于任何规范。

+

浏览器兼容性

+
+ {{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatIE("11")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/__definesetter__/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/__definesetter__/index.html new file mode 100644 index 0000000000..81a159b69f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/__definesetter__/index.html @@ -0,0 +1,92 @@ +--- +title: Object.prototype.__defineSetter__() +slug: Web/JavaScript/Reference/Global_Objects/Object/__defineSetter__ +translation_of: Web/JavaScript/Reference/Global_Objects/Object/__defineSetter__ +--- +
+ {{JSRef("Global_Objects", "Object")}} {{non-standard_header}} {{deprecated_header}}
+

概述

+

__defineSetter__ 方法可以将一个函数绑定在当前对象的指定属性上,当那个属性被赋值时,你所绑定的函数就会被调用。

+

语法

+
obj.__defineSetter__(prop, fun)
+

参数

+
+
+ prop
+
+ 一个字符串,表示指定的属性名。
+
+ fun
+
+ 一个函数,当试图去为 sprop 属性赋值时被调用。通常你要给这个函数指定一个参数:
+
function(val) { . . . }
+
+
+ val
+
+ 任意的参数名,在 fun 被调用时,该参数的值就是尝试给 sprop 属性所赋的值。
+
+
+
+

描述

+

__defineSetter__ 方法可以为一个已经存在的对象设置(新建或修改)访问器属性,而 {{jsxref("Operators/set", "对象字面量中的 set 语法", "", 1)}} 只能在新建一个对象时使用。

+

规范

+

不属于任何规范。

+

浏览器兼容性

+
+ {{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatIE("11")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/__lookupgetter__/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/__lookupgetter__/index.html new file mode 100644 index 0000000000..a94f293880 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/__lookupgetter__/index.html @@ -0,0 +1,121 @@ +--- +title: Object.prototype.__lookupGetter__() +slug: Web/JavaScript/Reference/Global_Objects/Object/__lookupGetter__ +translation_of: Web/JavaScript/Reference/Global_Objects/Object/__lookupGetter__ +--- +
{{JSRef("Global_Objects", "Object")}} {{ Non-standard_header }} {{ Deprecated_header }}
+ +

概述

+ +

__lookupGetter__ 方法会返回当前对象上指定属性的属性读取访问器函数(getter)。

+ +

语法

+ +
obj.__lookupGetter__(sprop)
+ +

参数

+ +
+
sprop
+
属性名
+
+ +

示例

+ +
var obj = {
+    get foo() {
+        return Math.random() > 0.5 ? "foo" : "bar";
+    }
+};
+
+obj.__lookupGetter__("foo")
+// (function (){return Math.random() > 0.5 ? "foo" : "bar"}) 
+ +

附注

+ +

__lookupGetter__ 方法是非标准的,我们应该使用标准中定义的方法来完成同样的事情,那就是 {{jsxref("Object.getOwnPropertyDescriptor()")}} 方法:

+ +
var obj = {
+    get foo() {
+        return Math.random() > 0.5 ? "foo" : "bar";
+    }
+};
+
+Object.getOwnPropertyDescriptor(obj, "foo").get
+// (function (){return Math.random() > 0.5 ? "foo" : "bar"})
+
+ +

如果那个访问器属性是继承来的,你还需要使用 {{jsxref("Object.getPrototypeOf()")}}:

+ +
var obj = {};
+var prototype = Object.getPrototypeOf(obj);
+Object.getOwnPropertyDescriptor(prototype, "foo").get
+// function __proto__() {[native code]}
+
+ +

规范

+ +

不属于任何规范。

+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{CompatVersionUnknown() }}{{CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown() }}{{CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/__lookupsetter__/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/__lookupsetter__/index.html new file mode 100644 index 0000000000..6481c7f16b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/__lookupsetter__/index.html @@ -0,0 +1,139 @@ +--- +title: Object.prototype.__lookupSetter__() +slug: Web/JavaScript/Reference/Global_Objects/Object/__lookupSetter__ +tags: + - 不建议使用 + - 原型 + - 对象 + - 方法 + - 过时的 + - 非标准 +translation_of: Web/JavaScript/Reference/Global_Objects/Object/__lookupSetter__ +--- +
{{JSRef}} {{deprecated_header}}
+ +
__lookupSetter__ 方法是用来返回一个对象的某个属性上绑定了 setter (设置器)的钩子函数的引用。
+ +
 
+ +

语法

+ +
obj.__lookupSetter__(sprop)
+ +

参数说明

+ +
+
sprop
+
一个字符串类型,表示要返回的 setter 钩子的函数名。
+
+ +

返回值

+ +

一个绑定了setter的特殊属性的函数引用。

+ +

描述

+ +

如果一个 setter 被定义在了一个对象的属性上,则不能直接通过该属性来获取引用 setter 所设置的钩子的函数,因为该属性是该函数的返回值,但,__lookupSetter__ 可以被用来获取对 setter 函数的引用。

+ +

不过现在可以使用标准的方法:

+ +

{{jsxref("Object.getOwnPropertyDescriptor()")}}.

+ +

示例

+ +
var obj = {
+  set foo(value) {
+    this.bar = value;
+  }
+};
+
+
+// 非标准,并且不推荐使用。
+obj.__lookupSetter__('foo')
+// (function(value) { this.bar = value; })
+
+
+// 标准且推荐使用的方式。
+Object.getOwnPropertyDescriptor(obj, 'foo').set;
+// (function(value) { this.bar = value; })
+
+ +

规范

+ + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-object.prototype.__lookupSetter__', 'Object.prototype.__lookupSetter__()')}}{{Spec2('ESDraft')}}包含在(规范性)附件中,用于Web浏览器的附加ECMAScript遗留功能(请注意,这份规范编撰的内容已经是准备实现的了)。
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatIE("11")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/assign/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/assign/index.html new file mode 100644 index 0000000000..13cc1854d6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/assign/index.html @@ -0,0 +1,321 @@ +--- +title: Object.assign() +slug: Web/JavaScript/Reference/Global_Objects/Object/assign +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Object + - Object.assign + - polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/Object/assign +--- +
{{JSRef}}
+ +

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。

+ +
{{EmbedInteractiveExample("pages/js/object-assign.html")}}
+ + + +

语法

+ +
Object.assign(target, ...sources)
+ +

参数

+ +
+
target
+
目标对象。
+
sources
+
源对象。
+
+ +

返回值

+ +

目标对象。

+ +

描述

+ +

如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。

+ +

Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用{{jsxref("Object.getOwnPropertyDescriptor()")}}和{{jsxref("Object.defineProperty()")}} 。

+ +

{{jsxref("String")}}类型和 {{jsxref("Symbol")}} 类型的属性都会被拷贝。

+ +

在出现错误的情况下,例如,如果属性不可写,会引发{{jsxref("TypeError")}},如果在引发错误之前添加了任何属性,则可以更改target对象。

+ +
+

注意,Object.assign 不会在那些source对象值为 {{jsxref("null")}} 或 {{jsxref("undefined")}} 的时候抛出错误。

+
+ +

Polyfill

+ +

这个 polyfill 不支持 symbol 属性, 由于 ES5 中本来就不存在 symbols :

+ +
if (typeof Object.assign !== 'function') {
+  // Must be writable: true, enumerable: false, configurable: true
+  Object.defineProperty(Object, "assign", {
+    value: function assign(target, varArgs) { // .length of function is 2
+      'use strict';
+      if (target === null || target === undefined) {
+        throw new TypeError('Cannot convert undefined or null to object');
+      }
+
+      var to = Object(target);
+
+      for (var index = 1; index < arguments.length; index++) {
+        var nextSource = arguments[index];
+
+        if (nextSource !== null && nextSource !== undefined) {
+          for (var nextKey in nextSource) {
+            // Avoid bugs when hasOwnProperty is shadowed
+            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
+              to[nextKey] = nextSource[nextKey];
+            }
+          }
+        }
+      }
+      return to;
+    },
+    writable: true,
+    configurable: true
+  });
+}
+ +

示例

+ +

复制一个对象

+ +
const obj = { a: 1 };
+const copy = Object.assign({}, obj);
+console.log(copy); // { a: 1 }
+
+ +

深拷贝问题

+ +

针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是(可枚举)属性值。

+ +

假如源值是一个对象的引用,它仅仅会复制其引用值。

+ +
const log = console.log;
+
+function test() {
+  'use strict';
+  let obj1 = { a: 0 , b: { c: 0}};
+  let obj2 = Object.assign({}, obj1);
+  log(JSON.stringify(obj2));
+  // { a: 0, b: { c: 0}}
+
+  obj1.a = 1;
+  log(JSON.stringify(obj1));
+  // { a: 1, b: { c: 0}}
+  log(JSON.stringify(obj2));
+  // { a: 0, b: { c: 0}}
+
+  obj2.a = 2;
+  log(JSON.stringify(obj1));
+  // { a: 1, b: { c: 0}}
+  log(JSON.stringify(obj2));
+  // { a: 2, b: { c: 0}}
+
+  obj2.b.c = 3;
+  log(JSON.stringify(obj1));
+  // { a: 1, b: { c: 3}}
+  log(JSON.stringify(obj2));
+  // { a: 2, b: { c: 3}}
+
+  // Deep Clone
+  obj1 = { a: 0 , b: { c: 0}};
+  let obj3 = JSON.parse(JSON.stringify(obj1));
+  obj1.a = 4;
+  obj1.b.c = 4;
+  log(JSON.stringify(obj3));
+  // { a: 0, b: { c: 0}}
+}
+
+test();
+
+ +

合并对象

+ +
const o1 = { a: 1 };
+const o2 = { b: 2 };
+const o3 = { c: 3 };
+
+const obj = Object.assign(o1, o2, o3);
+console.log(obj); // { a: 1, b: 2, c: 3 }
+console.log(o1);  // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。
+
+ +

合并具有相同属性的对象

+ +
const o1 = { a: 1, b: 1, c: 1 };
+const o2 = { b: 2, c: 2 };
+const o3 = { c: 3 };
+
+const obj = Object.assign({}, o1, o2, o3);
+console.log(obj); // { a: 1, b: 2, c: 3 }
+ +

属性被后续参数中具有相同属性的其他对象覆盖。

+ +

拷贝 symbol 类型的属性

+ +
const o1 = { a: 1 };
+const o2 = { [Symbol('foo')]: 2 };
+
+const obj = Object.assign({}, o1, o2);
+console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox)
+Object.getOwnPropertySymbols(obj); // [Symbol(foo)]
+ +

继承属性和不可枚举属性是不能拷贝的

+ +
const obj = Object.create({foo: 1}, { // foo 是个继承属性。
+    bar: {
+        value: 2  // bar 是个不可枚举属性。
+    },
+    baz: {
+        value: 3,
+        enumerable: true  // baz 是个自身可枚举属性。
+    }
+});
+
+const copy = Object.assign({}, obj);
+console.log(copy); // { baz: 3 }
+
+ +

原始类型会被包装为对象

+ +
const v1 = "abc";
+const v2 = true;
+const v3 = 10;
+const v4 = Symbol("foo")
+
+const obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
+// 原始类型会被包装,null 和 undefined 会被忽略。
+// 注意,只有字符串的包装对象才可能有自身可枚举属性。
+console.log(obj); // { "0": "a", "1": "b", "2": "c" }
+ +

异常会打断后续拷贝任务

+ +
const target = Object.defineProperty({}, "foo", {
+    value: 1,
+    writable: false
+}); // target 的 foo 属性是个只读属性。
+
+Object.assign(target, {bar: 2}, {foo2: 3, foo: 3, foo3: 3}, {baz: 4});
+// TypeError: "foo" is read-only
+// 注意这个异常是在拷贝第二个源对象的第二个属性时发生的。
+
+console.log(target.bar);  // 2,说明第一个源对象拷贝成功了。
+console.log(target.foo2); // 3,说明第二个源对象的第一个属性也拷贝成功了。
+console.log(target.foo);  // 1,只读属性不能被覆盖,所以第二个源对象的第二个属性拷贝失败了。
+console.log(target.foo3); // undefined,异常之后 assign 方法就退出了,第三个属性是不会被拷贝到的。
+console.log(target.baz);  // undefined,第三个源对象更是不会被拷贝到的。
+
+ +

拷贝访问器

+ +
const obj = {
+  foo: 1,
+  get bar() {
+    return 2;
+  }
+};
+
+let copy = Object.assign({}, obj);
+console.log(copy); // { foo: 1, bar: 2 } copy.bar的值来自obj.bar的getter函数的返回值
+
+// 下面这个函数会拷贝所有自有属性的属性描述符
+function completeAssign(target, ...sources) {
+  sources.forEach(source => {
+    let descriptors = Object.keys(source).reduce((descriptors, key) => {
+      descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
+      return descriptors;
+    }, {});
+
+    // Object.assign 默认也会拷贝可枚举的Symbols
+    Object.getOwnPropertySymbols(source).forEach(sym => {
+      let descriptor = Object.getOwnPropertyDescriptor(source, sym);
+      if (descriptor.enumerable) {
+        descriptors[sym] = descriptor;
+      }
+    });
+    Object.defineProperties(target, descriptors);
+  });
+  return target;
+}
+
+copy = completeAssign({}, obj);
+console.log(copy);
+// { foo:1, get bar() { return 2 } }
+
+ +

Polyfill

+ +

此{{Glossary("Polyfill","polyfill")}}不支持 symbol 属性,因为ES5 中根本没有 symbol :

+ +
if (typeof Object.assign != 'function') {
+  // Must be writable: true, enumerable: false, configurable: true
+  Object.defineProperty(Object, "assign", {
+    value: function assign(target, varArgs) { // .length of function is 2
+      'use strict';
+      if (target == null) { // TypeError if undefined or null
+        throw new TypeError('Cannot convert undefined or null to object');
+      }
+
+      let to = Object(target);
+
+      for (var index = 1; index < arguments.length; index++) {
+        var nextSource = arguments[index];
+
+        if (nextSource != null) { // Skip over if undefined or null
+          for (let nextKey in nextSource) {
+            // Avoid bugs when hasOwnProperty is shadowed
+            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
+              to[nextKey] = nextSource[nextKey];
+            }
+          }
+        }
+      }
+      return to;
+    },
+    writable: true,
+    configurable: true
+  });
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES6', '#sec-object.assign', 'Object.assign')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-object.assign', 'Object.assign')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.assign")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/constructor/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/constructor/index.html new file mode 100644 index 0000000000..470072ebe7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/constructor/index.html @@ -0,0 +1,235 @@ +--- +title: Object.prototype.constructor +slug: Web/JavaScript/Reference/Global_Objects/Object/constructor +tags: + - JavaScript + - Object + - Property + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Object/constructor +--- +

{{JSRef}}

+ +

返回创建实例对象的 {{jsxref("Object")}} 构造函数的引用。注意,此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串。对原始类型来说,如1true"test",该值只可读。

+ +

描述

+ +

所有对象都会从它的原型上继承一个 constructor 属性:

+ +
var o = {};
+o.constructor === Object; // true
+
+var o = new Object;
+o.constructor === Object; // true
+
+var a = [];
+a.constructor === Array; // true
+
+var a = new Array;
+a.constructor === Array // true
+
+var n = new Number(3);
+n.constructor === Number; // true
+ +

示例

+ +

打印一个对象的构造函数

+ +

以下示例创建一个原型,Tree,以及该类型的对象,即theTree。 然后打印theTree对象的constructor属性。

+ +
function Tree(name) {
+   this.name = name;
+}
+
+var theTree = new Tree("Redwood");
+console.log( "theTree.constructor is " + theTree.constructor );
+ +

打印输出:

+ +
theTree.constructor is function Tree(name) {
+    this.name = name;
+}
+ +

改变对象的 constructor

+ +

下面的例子展示了如何修改基本类型对象的 constructor 属性的值。只有 true, 1"test" 的不受影响,因为创建他们的是只读的原生构造函数(native constructors)。这个例子也说明了依赖一个对象的 constructor 属性并不安全。

+ +
function Type() { };
+
+var	types = [
+	new Array,
+    [],
+	new Boolean,
+    true,        // remains unchanged
+	new Date,
+	new Error,
+	new Function,
+	function(){},
+	Math,
+	new Number,
+	1,           // remains unchanged
+	new Object,
+	{},
+	new RegExp,
+	/(?:)/,
+	new String,
+	"test"       // remains unchanged
+];
+
+for(var i = 0; i < types.length; i++) {
+	types[i].constructor = Type;
+	types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ];
+};
+
+console.log( types.join("\n") );
+
+ +

此示例显示以下输出:

+ +
function Type() {},false,
+function Type() {},false,
+function Type() {},false,false
+function Boolean() {
+    [native code]
+},false,true
+function Type() {},false,Mon Sep 01 2014 16:03:49 GMT+0600
+function Type() {},false,Error
+function Type() {},false,function anonymous() {
+
+}
+function Type() {},false,function () {}
+function Type() {},false,[object Math]
+function Type() {},false,0
+function Number() {
+    [native code]
+},false,1
+function Type() {},false,[object Object]
+function Type() {},false,[object Object]
+function Type() {},false,/(?:)/
+function Type() {},false,/(?:)/
+function Type() {},false,
+function String() {
+    [native code]
+},false,test
+
+ + + +

改变函数的 constructor

+ +

大多数情况下,此属性用于定义一个构造函数,并使用new和继承原型链进一步调用它。

+ +
function Parent() {}
+Parent.prototype.parentMethod = function parentMethod() {};
+
+function Child() {}
+Child.prototype = Object.create(Parent.prototype); // re-define child prototype to Parent prototype
+
+Child.prototype.constructor = Child; // return original constructor to Child
+ +

但为什么我们需要在这里执行最后一行?很不幸正确答案是 - 看情况而定。

+ +

让我们来尝试定义在哪些情况下,重新分配原始构造函数会发挥重要作用,以及在什么时候它就是额外的未使用的(无效的)代码行。

+ +

试想下一种情况:该对象具有创建自身的create方法。

+ +
function Parent() {};
+function CreatedConstructor() {}
+
+CreatedConstructor.prototype = Object.create(Parent.prototype);
+
+CreatedConstructor.prototype.create = function create() {
+  return new this.constructor();
+}
+
+new CreatedConstructor().create().create(); // error undefined is not a function since constructor === Parent
+
+ +

在上面的示例中,将显示异常,因为构造函数链接到Parent。

+ +

为了避免它,只需分配您将要使用的必要构造函数。

+ +
function Parent() {};
+function CreatedConstructor() {}
+
+CreatedConstructor.prototype = Object.create(Parent.prototype);
+CreatedConstructor.prototype.constructor = CreatedConstructor; // set right constructor for further using
+
+CreatedConstructor.prototype.create = function create() {
+  return new this.constructor();
+}
+
+new CreatedConstructor().create().create(); // it's pretty fine
+ +

好的,现在很清楚为什么更改构造函数会很有用。

+ +

让我们再考虑一个案例。

+ +
function ParentWithStatic() {}
+
+ParentWithStatic.startPosition = { x: 0, y:0 };
+ParentWithStatic.getStartPosition = function getStartPosition() {
+  return this.startPosition;
+}
+
+function Child(x, y) {
+  this.position = {
+    x: x,
+    y: y
+  };
+}
+
+Child.prototype = Object.create(ParentWithStatic.prototype);
+Child.prototype.constructor = Child;
+
+Child.prototype.getOffsetByInitialPosition = function getOffsetByInitialPosition() {
+  var position = this.position;
+  var startPosition = this.constructor.getStartPosition(); // error undefined is not a function, since the constructor is Child
+
+  return {
+    offsetX: startPosition.x - position.x,
+    offsetY: startPosition.y - position.y
+  }
+};
+ +

对于此示例,我们需要保持父构造函数继续正常工作。

+ +

总结:手动设置或更新构造函数可能会导致不同且有时令人困惑的后果。为了防止它,只需在每个特定情况下定义构造函数的角色。在大多数情况下,不使用构造函数,并且不需要重新分配构造函数。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.2.4.1', 'Object.prototype.constructor')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-object.prototype.constructor', 'Object.prototype.constructor')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.prototype.constructor', 'Object.prototype.constructor')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.constructor")}}

diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/count/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/count/index.html new file mode 100644 index 0000000000..c7dfb12f2b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/count/index.html @@ -0,0 +1,88 @@ +--- +title: Object.prototype.__count__ +slug: Web/JavaScript/Reference/Global_Objects/Object/count +tags: + - JavaScript + - Object + - Obsolete + - Property + - Prototype +translation_of: Archive/Web/JavaScript/Object.count +--- +
{{JSRef}} {{obsolete_header("2")}}
+ +

 __count__ 属性曾经用来存放对象的可枚举的属性的个数,但是已经被废除。

+ +

语法

+ +
obj.__count__
+ +

示例

+ +
{ 1: 1 }.__count__              // 1
+[].__count__                    // 0
+[1].__count__                   // 1
+[1, /* hole */, 2, 3].__count__ // 3
+
+ +

详细说明

+ +

无需详细说明

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

更多请参看

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/create/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/create/index.html new file mode 100644 index 0000000000..4cc48defc5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/create/index.html @@ -0,0 +1,227 @@ +--- +title: Object.create() +slug: Web/JavaScript/Reference/Global_Objects/Object/create +tags: + - ECMAScript5 + - JavaScript + - Method + - Object + - Reference + - polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/Object/create +--- +
{{JSRef}}
+ +

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)

+ +
{{EmbedInteractiveExample("pages/js/object-create.html", "taller")}}
+ + + +

语法

+ +
Object.create(proto,[propertiesObject])
+ +

参数

+ +
+
proto
+
新创建对象的原型对象。
+
propertiesObject
+
可选。需要传入一个对象,该对象的属性类型参照{{jsxref("Object.defineProperties()")}}的第二个参数。如果该参数被指定且不为 {{jsxref("undefined")}},该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。
+
+ +

返回值

+ +

一个新对象,带着指定的原型对象和属性。

+ +

例外

+ +

如果propertiesObject参数是 {{jsxref("null")}} 或非原始包装对象,则抛出一个 {{jsxref("TypeError")}} 异常。

+ +

例子

+ +

用 Object.create实现类式继承

+ +

下面的例子演示了如何使用Object.create()来实现类式继承。这是一个所有版本JavaScript都支持的单继承。

+ +
// Shape - 父类(superclass)
+function Shape() {
+  this.x = 0;
+  this.y = 0;
+}
+
+// 父类的方法
+Shape.prototype.move = function(x, y) {
+  this.x += x;
+  this.y += y;
+  console.info('Shape moved.');
+};
+
+// Rectangle - 子类(subclass)
+function Rectangle() {
+  Shape.call(this); // call super constructor.
+}
+
+// 子类续承父类
+Rectangle.prototype = Object.create(Shape.prototype);
+Rectangle.prototype.constructor = Rectangle;
+
+var rect = new Rectangle();
+
+console.log('Is rect an instance of Rectangle?',
+  rect instanceof Rectangle); // true
+console.log('Is rect an instance of Shape?',
+  rect instanceof Shape); // true
+rect.move(1, 1); // Outputs, 'Shape moved.'
+ +

如果你希望能继承到多个对象,则可以使用混入的方式。

+ +
function MyClass() {
+     SuperClass.call(this);
+     OtherSuperClass.call(this);
+}
+
+// 继承一个类
+MyClass.prototype = Object.create(SuperClass.prototype);
+// 混合其它
+Object.assign(MyClass.prototype, OtherSuperClass.prototype);
+// 重新指定constructor
+MyClass.prototype.constructor = MyClass;
+
+MyClass.prototype.myMethod = function() {
+     // do a thing
+};
+
+ +

Object.assign 会把  OtherSuperClass原型上的函数拷贝到 MyClass原型上,使 MyClass 的所有实例都可用 OtherSuperClass 的方法。Object.assign 是在 ES2015 引入的,且可用 polyfilled。要支持旧浏览器的话,可用使用 jQuery.extend() 或者 _.assign()

+ +

使用 Object.createpropertyObject参数

+ +
var o;
+
+// 创建一个原型为null的空对象
+o = Object.create(null);
+
+
+o = {};
+// 以字面量方式创建的空对象就相当于:
+o = Object.create(Object.prototype);
+
+
+o = Object.create(Object.prototype, {
+  // foo会成为所创建对象的数据属性
+  foo: {
+    writable:true,
+    configurable:true,
+    value: "hello"
+  },
+  // bar会成为所创建对象的访问器属性
+  bar: {
+    configurable: false,
+    get: function() { return 10 },
+    set: function(value) {
+      console.log("Setting `o.bar` to", value);
+    }
+  }
+});
+
+
+function Constructor(){}
+o = new Constructor();
+// 上面的一句就相当于:
+o = Object.create(Constructor.prototype);
+// 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码
+
+
+// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
+o = Object.create({}, { p: { value: 42 } })
+
+// 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
+o.p = 24
+o.p
+//42
+
+o.q = 12
+for (var prop in o) {
+   console.log(prop)
+}
+//"q"
+
+delete o.p
+//false
+
+//创建一个可写的,可枚举的,可配置的属性p
+o2 = Object.create({}, {
+  p: {
+    value: 42,
+    writable: true,
+    enumerable: true,
+    configurable: true
+  }
+});
+ +

Polyfill

+ +

这个 polyfill 涵盖了主要的应用场景,它创建一个已经选择了原型的新对象,但没有把第二个参数考虑在内。

+ +

请注意,尽管在 ES5 中 Object.create支持设置为[[Prototype]]null,但因为那些ECMAScript5以前版本限制,此 polyfill 无法支持该特性。

+ +
if (typeof Object.create !== "function") {
+    Object.create = function (proto, propertiesObject) {
+        if (typeof proto !== 'object' && typeof proto !== 'function') {
+            throw new TypeError('Object prototype may only be an Object: ' + proto);
+        } else if (proto === null) {
+            throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
+        }
+
+        if (typeof propertiesObject !== 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
+
+        function F() {}
+        F.prototype = proto;
+
+        return new F();
+    };
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.5', 'Object.create')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.8.5.
{{SpecName('ES2015', '#sec-object.create', 'Object.create')}}{{Spec2('ES2015')}}
{{SpecName('ESDraft', '#sec-object.create', 'Object.create')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.create")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/defineproperties/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/defineproperties/index.html new file mode 100644 index 0000000000..c36b799695 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/defineproperties/index.html @@ -0,0 +1,183 @@ +--- +title: Object.defineProperties() +slug: Web/JavaScript/Reference/Global_Objects/Object/defineProperties +tags: + - ECMAScript 5 + - JavaScript + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/defineProperties +--- +

{{JSRef}}

+ +

Object.defineProperties() 方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。

+ +

语法

+ +
Object.defineProperties(objprops)
+ +

参数

+ +
+
obj
+
在其上定义或修改属性的对象。
+
props
+
要定义其可枚举属性或修改的属性描述符的对象。对象中存在的属性描述符主要有两种:数据描述符和访问器描述符(更多详情,请参阅{{jsxref("Object.defineProperty()")}})。描述符具有以下键:
+
+
+
configurable
+
true 当且仅当该属性描述符的类型可以被改变并且该属性可以从对应对象中删除。
+ 默认为 false
+
enumerable
+
true 当且仅当在枚举相应对象上的属性时该属性显现。
+ 默认为 false
+
+ +
+
value
+
与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。
+ 默认为 {{jsxref("undefined")}}.
+
writable
+
true当且仅当与该属性相关联的值可以用{{jsxref("Operators/Assignment_Operators", "assignment operator", "", 1)}}改变时。
+ 默认为 false
+
+ +
+
get
+
作为该属性的 getter 函数,如果没有 getter 则为{{jsxref("undefined")}}。函数返回值将被用作属性的值。
+ 默认为 {{jsxref("undefined")}}
+
set
+
作为属性的 setter 函数,如果没有 setter 则为{{jsxref("undefined")}}。函数将仅接受参数赋值给该属性的新值。
+ 默认为 {{jsxref("undefined")}}
+
+
+
+ +

返回值

+ +

传递给函数的对象。

+ +

描述

+ +

Object.defineProperties本质上定义了obj 对象上props的可枚举属性相对应的所有属性。

+ +

例子

+ +
var obj = {};
+Object.defineProperties(obj, {
+  'property1': {
+    value: true,
+    writable: true
+  },
+  'property2': {
+    value: 'Hello',
+    writable: false
+  }
+  // etc. etc.
+});
+ +

Polyfill

+ +

假设一个原始的执行环境,所有的名称和属性都引用它们的初始值,Object.defineProperties几乎完全等同于(注意isCallable中的注释)以下JavaScript中的重新实现:

+ +
function defineProperties(obj, properties) {
+  function convertToDescriptor(desc) {
+    function hasProperty(obj, prop) {
+      return Object.prototype.hasOwnProperty.call(obj, prop);
+    }
+
+    function isCallable(v) {
+      // NB: modify as necessary if other values than functions are callable.
+      return typeof v === 'function';
+    }
+
+    if (typeof desc !== 'object' || desc === null)
+      throw new TypeError('bad desc');
+
+    var d = {};
+
+    if (hasProperty(desc, 'enumerable'))
+      d.enumerable = !!desc.enumerable;
+    if (hasProperty(desc, 'configurable'))
+      d.configurable = !!desc.configurable;
+    if (hasProperty(desc, 'value'))
+      d.value = desc.value;
+    if (hasProperty(desc, 'writable'))
+      d.writable = !!desc.writable;
+    if (hasProperty(desc, 'get')) {
+      var g = desc.get;
+
+      if (!isCallable(g) && typeof g !== 'undefined')
+        throw new TypeError('bad get');
+      d.get = g;
+    }
+    if (hasProperty(desc, 'set')) {
+      var s = desc.set;
+      if (!isCallable(s) && typeof s !== 'undefined')
+        throw new TypeError('bad set');
+      d.set = s;
+    }
+
+    if (('get' in d || 'set' in d) && ('value' in d || 'writable' in d))
+      throw new TypeError('identity-confused descriptor');
+
+    return d;
+  }
+
+  if (typeof obj !== 'object' || obj === null)
+    throw new TypeError('bad obj');
+
+  properties = Object(properties);
+
+  var keys = Object.keys(properties);
+  var descs = [];
+
+  for (var i = 0; i < keys.length; i++)
+    descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);
+
+  for (var i = 0; i < descs.length; i++)
+    Object.defineProperty(obj, descs[i][0], descs[i][1]);
+
+  return obj;
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.7', 'Object.defineProperties')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.8.5
{{SpecName('ES6', '#sec-object.defineproperties', 'Object.defineProperties')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-object.defineproperties', 'Object.defineProperties')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Object.defineProperties")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/defineproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/defineproperty/index.html new file mode 100644 index 0000000000..beaca31a6a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/defineproperty/index.html @@ -0,0 +1,545 @@ +--- +title: Object.defineProperty() +slug: Web/JavaScript/Reference/Global_Objects/Object/defineProperty +tags: + - ECMAScript 5 + - JavaScript + - JavaScript 1.8.5 + - Method + - Object + - 对象 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Object/defineProperty +--- +
{{JSRef}}
+ +

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

+ +
+

备注:应当直接在 {{jsxref("Object")}} 构造器对象上调用此方法,而不是在任意一个 Object 类型的实例上调用。

+
+ +
{{EmbedInteractiveExample("pages/js/object-defineproperty.html")}}
+ + + +

语法

+ +
Object.defineProperty(obj, prop, descriptor)
+ +

参数

+ +
+
obj
+
要定义属性的对象。
+
prop
+
要定义或修改的属性的名称或 {{jsxref("Symbol")}} 。
+
descriptor
+
要定义或修改的属性描述符。
+
+ +

返回值

+ +

被传递给函数的对象。

+ +
+

在ES6中,由于 Symbol类型的特殊性,用Symbol类型的值来做对象的key与常规的定义或修改不同,而Object.defineProperty 是定义key为Symbol的属性的方法之一。

+
+ +

描述

+ +

该方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,在枚举对象属性时会被枚举到({{jsxref("Statements/for...in", "for...in")}} 或 {{jsxref("Object.keys")}} 方法),可以改变这些属性的值,也可以{{jsxref("Operators/delete", "删除")}}这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改(immutable)的。

+ +

对象里目前存在的属性描述符有两种主要形式:数据描述符存取描述符数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。

+ +

这两种描述符都是对象。它们共享以下可选键值(默认值是指在使用 Object.defineProperty() 定义属性时的默认值):

+ +
+
configurable
+
当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。
+ 默认为 false
+
enumerable
+
当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。
+ 默认为 false
+
+ +

数据描述符还具有以下可选键值:

+ +
+
value
+
该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。
+ 默认为 {{jsxref("undefined")}}
+
writable
+
当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被{{jsxref("Operators/Assignment_Operators", "赋值运算符")}}改变。
+ 默认为 false
+
+ +

存取描述符还具有以下可选键值:

+ +
+
get
+
属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。
+ 默认为 {{jsxref("undefined")}}
+
set
+
属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。
+ 默认为 {{jsxref("undefined")}}
+
+ +

描述符默认值汇总

+ + + +

描述符可拥有的键值

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
configurableenumerablevaluewritablegetset
数据描述符可以可以可以可以不可以不可以
存取描述符可以可以不可以不可以可以可以
+
+
+ +

如果一个描述符不具有 valuewritablegetset 中的任意一个键,那么它将被认为是一个数据描述符。如果一个描述符同时拥有 valuewritablegetset 键,则会产生一个异常。

+ +

记住,这些选项不一定是自身属性,也要考虑继承来的属性。为了确认保留这些默认值,在设置之前,可能要冻结 {{jsxref("Object.prototype")}},明确指定所有的选项,或者通过 {{jsxref("Object.create", "Object.create(null)")}} 将 {{jsxref("Object.prototype.__proto__", "__proto__")}} 属性指向 {{jsxref("null")}}。

+ +
// 使用 __proto__
+var obj = {};
+var descriptor = Object.create(null); // 没有继承的属性
+// 默认没有 enumerable,没有 configurable,没有 writable
+descriptor.value = 'static';
+Object.defineProperty(obj, 'key', descriptor);
+
+// 显式
+Object.defineProperty(obj, "key", {
+  enumerable: false,
+  configurable: false,
+  writable: false,
+  value: "static"
+});
+
+// 循环使用同一对象
+function withValue(value) {
+  var d = withValue.d || (
+    withValue.d = {
+      enumerable: false,
+      writable: false,
+      configurable: false,
+      value: null
+    }
+  );
+  d.value = value;
+  return d;
+}
+// ... 并且 ...
+Object.defineProperty(obj, "key", withValue("static"));
+
+// 如果 freeze 可用, 防止后续代码添加或删除对象原型的属性
+// (value, get, set, enumerable, writable, configurable)
+(Object.freeze||Object)(Object.prototype);
+ +

示例

+ +

如果你想了解如何使用 Object.defineProperty 方法和类二进制标记语法,可以看看这些额外示例

+ +

创建属性

+ +

如果对象中不存在指定的属性,Object.defineProperty() 会创建这个属性。当描述符中省略某些字段时,这些字段将使用它们的默认值。

+ +
var o = {}; // 创建一个新对象
+
+// 在对象中添加一个属性与数据描述符的示例
+Object.defineProperty(o, "a", {
+  value : 37,
+  writable : true,
+  enumerable : true,
+  configurable : true
+});
+
+// 对象 o 拥有了属性 a,值为 37
+
+// 在对象中添加一个设置了存取描述符属性的示例
+var bValue = 38;
+Object.defineProperty(o, "b", {
+  // 使用了方法名称缩写(ES2015 特性)
+  // 下面两个缩写等价于:
+  // get : function() { return bValue; },
+  // set : function(newValue) { bValue = newValue; },
+  get() { return bValue; },
+  set(newValue) { bValue = newValue; },
+  enumerable : true,
+  configurable : true
+});
+
+o.b; // 38
+// 对象 o 拥有了属性 b,值为 38
+// 现在,除非重新定义 o.b,o.b 的值总是与 bValue 相同
+
+// 数据描述符和存取描述符不能混合使用
+Object.defineProperty(o, "conflict", {
+  value: 0x9f91102,
+  get() { return 0xdeadbeef; }
+});
+// 抛出错误 TypeError: value appears only in data descriptors, get appears only in accessor descriptors
+
+ +

修改属性

+ +

如果属性已经存在,Object.defineProperty()将尝试根据描述符中的值以及对象当前的配置来修改这个属性。如果旧描述符将其configurable 属性设置为false,则该属性被认为是“不可配置的”,并且没有属性可以被改变(除了单向改变 writable 为 false)。当属性不可配置时,不能在数据和访问器属性类型之间切换。

+ +

当试图改变不可配置属性(除了 valuewritable 属性之外)的值时,会抛出{{jsxref("TypeError")}},除非当前值和新值相同。

+ +

Writable 属性

+ +

writable 属性设置为 false 时,该属性被称为“不可写的”。它不能被重新赋值。

+ +
var o = {}; // 创建一个新对象
+
+Object.defineProperty(o, 'a', {
+  value: 37,
+  writable: false
+});
+
+console.log(o.a); // logs 37
+o.a = 25; // No error thrown
+// (it would throw in strict mode,
+// even if the value had been the same)
+console.log(o.a); // logs 37. The assignment didn't work.
+
+// strict mode
+(function() {
+  'use strict';
+  var o = {};
+  Object.defineProperty(o, 'b', {
+    value: 2,
+    writable: false
+  });
+  o.b = 3; // throws TypeError: "b" is read-only
+  return o.b; // returns 2 without the line above
+}());
+ +

如示例所示,试图写入非可写属性不会改变它,也不会引发错误。

+ +

Enumerable 属性

+ +

enumerable 定义了对象的属性是否可以在 {{jsxref("Statements/for...in", "for...in")}} 循环和 {{jsxref("Object.keys()")}} 中被枚举。

+ +
var o = {};
+Object.defineProperty(o, "a", { value : 1, enumerable: true });
+Object.defineProperty(o, "b", { value : 2, enumerable: false });
+Object.defineProperty(o, "c", { value : 3 }); // enumerable 默认为 false
+o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则 enumerable 为 true
+Object.defineProperty(o, Symbol.for('e'), {
+  value: 5,
+  enumerable: true
+});
+Object.defineProperty(o, Symbol.for('f'), {
+  value: 6,
+  enumerable: false
+});
+
+for (var i in o) {
+  console.log(i);
+}
+// logs 'a' and 'd' (in undefined order)
+
+Object.keys(o); // ['a', 'd']
+
+o.propertyIsEnumerable('a'); // true
+o.propertyIsEnumerable('b'); // false
+o.propertyIsEnumerable('c'); // false
+o.propertyIsEnumerable('d'); // true
+o.propertyIsEnumerable(Symbol.for('e')); // true
+o.propertyIsEnumerable(Symbol.for('f')); // false
+
+var p = { ...o }
+p.a // 1
+p.b // undefined
+p.c // undefined
+p.d // 4
+p[Symbol.for('e')] // 5
+p[Symbol.for('f')] // undefined
+ +

Configurable 属性

+ +

configurable 特性表示对象的属性是否可以被删除,以及除 valuewritable 特性外的其他特性是否可以被修改。

+ +
var o = {};
+Object.defineProperty(o, 'a', {
+  get() { return 1; },
+  configurable: false
+});
+
+Object.defineProperty(o, 'a', {
+  configurable: true
+}); // throws a TypeError
+Object.defineProperty(o, 'a', {
+  enumerable: true
+}); // throws a TypeError
+Object.defineProperty(o, 'a', {
+  set() {}
+}); // throws a TypeError (set was undefined previously)
+Object.defineProperty(o, 'a', {
+  get() { return 1; }
+}); // throws a TypeError
+// (even though the new get does exactly the same thing)
+Object.defineProperty(o, 'a', {
+  value: 12
+}); // throws a TypeError // ('value' can be changed when 'configurable' is false but not in this case due to 'get' accessor)
+
+console.log(o.a); // logs 1
+delete o.a; // Nothing happens
+console.log(o.a); // logs 1
+ +

如果 o.aconfigurable 属性为 true,则不会抛出任何错误,并且,最后,该属性会被删除。

+ +

添加多个属性和默认值

+ +

考虑特性被赋予的默认特性值非常重要,通常,使用点运算符和 Object.defineProperty() 为对象的属性赋值时,数据描述符中的属性默认值是不同的,如下例所示。

+ +
var o = {};
+
+o.a = 1;
+// 等同于:
+Object.defineProperty(o, "a", {
+  value: 1,
+  writable: true,
+  configurable: true,
+  enumerable: true
+});
+
+
+// 另一方面,
+Object.defineProperty(o, "a", { value : 1 });
+// 等同于:
+Object.defineProperty(o, "a", {
+  value: 1,
+  writable: false,
+  configurable: false,
+  enumerable: false
+});
+
+ +

自定义 Setters 和 Getters

+ +

下面的例子展示了如何实现一个自存档对象。当设置temperature 属性时,archive 数组会收到日志条目。

+ +
function Archiver() {
+  var temperature = null;
+  var archive = [];
+
+  Object.defineProperty(this, 'temperature', {
+    get: function() {
+      console.log('get!');
+      return temperature;
+    },
+    set: function(value) {
+      temperature = value;
+      archive.push({ val: temperature });
+    }
+  });
+
+  this.getArchive = function() { return archive; };
+}
+
+var arc = new Archiver();
+arc.temperature; // 'get!'
+arc.temperature = 11;
+arc.temperature = 13;
+arc.getArchive(); // [{ val: 11 }, { val: 13 }]
+ +

下面这个例子中,getter 总是会返回一个相同的值。

+ +
var pattern = {
+    get: function () {
+        return 'I alway return this string,whatever you have assigned';
+    },
+    set: function () {
+        this.myname = 'this is my name string';
+    }
+};
+
+
+function TestDefineSetAndGet() {
+    Object.defineProperty(this, 'myproperty', pattern);
+}
+
+
+var instance = new TestDefineSetAndGet();
+instance.myproperty = 'test';
+
+// 'I alway return this string,whatever you have assigned'
+console.log(instance.myproperty);
+// 'this is my name string'
+console.log(instance.myname);
+ +

继承属性

+ +

如果访问者的属性是被继承的,它的 getset 方法会在子对象的属性被访问或者修改时被调用。如果这些方法用一个变量存值,该值会被所有对象共享。

+ +
function myclass() {
+}
+
+var value;
+Object.defineProperty(myclass.prototype, "x", {
+  get() {
+    return value;
+  },
+  set(x) {
+    value = x;
+  }
+});
+
+var a = new myclass();
+var b = new myclass();
+a.x = 1;
+console.log(b.x); // 1
+
+ +

这可以通过将值存储在另一个属性中解决。在 getset 方法中,this 指向某个被访问和修改属性的对象。

+ +
function myclass() {
+}
+
+Object.defineProperty(myclass.prototype, "x", {
+  get() {
+    return this.stored_x;
+  },
+  set(x) {
+    this.stored_x = x;
+  }
+});
+
+var a = new myclass();
+var b = new myclass();
+a.x = 1;
+console.log(b.x); // undefined
+ +

不像访问者属性,值属性始终在对象自身上设置,而不是一个原型。然而,如果一个不可写的属性被继承,它仍然可以防止修改对象的属性。

+ +
function myclass() {
+}
+
+myclass.prototype.x = 1;
+Object.defineProperty(myclass.prototype, "y", {
+  writable: false,
+  value: 1
+});
+
+var a = new myclass();
+a.x = 2;
+console.log(a.x); // 2
+console.log(myclass.prototype.x); // 1
+a.y = 2; // Ignored, throws in strict mode
+console.log(a.y); // 1
+console.log(myclass.prototype.y); // 1
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES5.1', '#sec-15.2.3.6', 'Object.defineProperty')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.8.5.
{{SpecName('ES6', '#sec-object.defineproperty', 'Object.defineProperty')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.defineproperty', 'Object.defineProperty')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Object.defineProperty")}}

+ +

兼容性问题

+ +

重定义数组 Array 对象的 length 属性

+ +

重定义数组的 {{jsxref("Array.length", "length")}} 属性是可能的,但是会受到一般的重定义限制。({{jsxref("Array.length", "length")}} 属性初始为 non-configurable,non-enumerable 以及 writable。对于一个内容不变的数组,改变其 {{jsxref("Array.length", "length")}} 属性的值或者使它变为 non-writable 是可能的。但是改变其可枚举性和可配置性或者当它是 non-writable 时尝试改变它的值或是可写性,这两者都是不允许的。)然而,并不是所有的浏览器都允许 Array.length 的重定义。

+ +

在 Firefox 4 至 22 版本中,尝试重定义数组的 length 属性都会抛出 {{jsxref("TypeError")}} 异常。

+ +

一些版本的 Chrome 中,Object.defineProperty() 在某些情况下会忽略不同于数组当前{{jsxref("Array.length", "length")}}属性的length值。有些情况下改变可写性并不起作用(也不抛出异常)。同时,比如{{jsxref("Array.prototype.push")}}的一些数组操作方法也不会考虑不可读的length属性。

+ +

一些版本的 Safari 中,Object.defineProperty() 在某些情况下会忽略不同于数组当前{{jsxref("Array.length", "length")}}属性的length值。尝试改变可写性的操作会正常执行而不抛出错误,但事实上并未改变属性的可写性。

+ +

只在Internet Explorer 9及以后版本和Firefox 23及以后版本中,才完整地正确地支持数组 {{jsxref("Array.length", "length")}} 属性的重新定义。目前不要依赖于重定义数组 {{jsxref("Array.length", "length")}} 属性能够起作用,或在特定情形下起作用。与此同时,即使你能够依赖于它,你也没有合适的理由这样做

+ +

Internet Explorer 8 特别备注

+ +

Internet Explorer 8 实现了 Object.defineProperty() 方法,但只能在 DOM 对象上使用。 需要注意的一些事情:

+ + + +

Chrome 37(及以下)特别备注

+ +

Chrome 37(及以下)有一个 bug,使用 writable: false 定义原型 prototype 属性,或者函数时,不会像预期的那样工作。

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/entries/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/entries/index.html new file mode 100644 index 0000000000..6e704940a5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/entries/index.html @@ -0,0 +1,134 @@ +--- +title: Object.entries() +slug: Web/JavaScript/Reference/Global_Objects/Object/entries +tags: + - JavaScript + - Method + - Object + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Object/entries +--- +
{{JSRef}}
+ +

Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 {{jsxref("Statements/for...in", "for...in")}} 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。

+ +
{{EmbedInteractiveExample("pages/js/object-entries.html", "taller")}}
+ + + +

语法

+ +
Object.entries(obj)
+ +

参数

+ +
+
obj
+
可以返回其可枚举属性的键值对的对象。
+
+ +

返回值

+ +
+
给定对象自身可枚举属性的键值对数组。
+
+ +

描述

+ +

Object.entries()返回一个数组,其元素是与直接在object上找到的可枚举属性键值对相对应的数组。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。

+ +

示例

+ +
const obj = { foo: 'bar', baz: 42 };
+console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
+
+// array like object
+const obj = { 0: 'a', 1: 'b', 2: 'c' };
+console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
+
+// array like object with random key ordering
+const anObj = { 100: 'a', 2: 'b', 7: 'c' };
+console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]
+
+// getFoo is property which isn't enumerable
+const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } });
+myObj.foo = 'bar';
+console.log(Object.entries(myObj)); // [ ['foo', 'bar'] ]
+
+// non-object argument will be coerced to an object
+console.log(Object.entries('foo')); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]
+
+// iterate through key-value gracefully
+const obj = { a: 5, b: 7, c: 9 };
+for (const [key, value] of Object.entries(obj)) {
+  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
+}
+
+// Or, using array extras
+Object.entries(obj).forEach(([key, value]) => {
+console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
+});
+ +

Object转换为Map

+ +

{{jsxref("Map", "new Map()")}} 构造函数接受一个可迭代的entries。借助Object.entries方法你可以很容易的将{{jsxref("Object")}}转换为{{jsxref("Map")}}:

+ +
var obj = { foo: "bar", baz: 42 };
+var map = new Map(Object.entries(obj));
+console.log(map); // Map { foo: "bar", baz: 42 }
+ +

Polyfill

+ +

要在较旧环境中添加兼容的Object.entries支持,你可以在 tc39/proposal-object-values-entries 中找到Object.entries的示例(如果你不需要任何对IE的支持),在 es-shims/Object.entries 资料库中的一个polyfill,或者你可以使用下面列出的简易 polyfill。

+ +
if (!Object.entries)
+  Object.entries = function( obj ){
+    var ownProps = Object.keys( obj ),
+        i = ownProps.length,
+        resArray = new Array(i); // preallocate the Array
+    while (i--)
+      resArray[i] = [ownProps[i], obj[ownProps[i]]];
+
+    return resArray;
+  };
+ +

对于上述 polyfill 代码片段,如果你需要 IE9 以下的支持,那么你还需要一个 Object.keys polyfill(如 {{jsxref("Object.keys")}}页面上的)。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-object.entries', 'Object.entries')}}{{Spec2('ESDraft')}}Initial definition.
{{SpecName('ES8', '#sec-object.entries', 'Object.entries')}}{{Spec2('ES8')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.entries")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/eval/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/eval/index.html new file mode 100644 index 0000000000..e823c314a8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/eval/index.html @@ -0,0 +1,85 @@ +--- +title: Object.prototype.eval() +slug: Web/JavaScript/Reference/Global_Objects/Object/eval +translation_of: Archive/Web/JavaScript/Object.eval +--- +
{{JSRef}} {{obsolete_header}}
+ +

Object.eval() 方法用于在对象的上下文中对 JavaScript 代码字符串求值,但该方法已被移除。

+ +

语法

+ +
obj.eval(string)
+ +

参数

+ +
+
string
+
包含任意 JavaScript 表达式、语句或一组语句的字符串。表达式中可包含已有对象的变量与属性。
+
+ +

描述

+ +

eval 方法已从对象方法中移除。可使用全局 {{jsxref("Global_Objects/eval", "eval()")}} 函数替代该方法。

+ +

规范

+ +

暂无规范

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/freeze/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/freeze/index.html new file mode 100644 index 0000000000..b72dbbf9c0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/freeze/index.html @@ -0,0 +1,206 @@ +--- +title: Object.freeze() +slug: Web/JavaScript/Reference/Global_Objects/Object/freeze +tags: + - ECMAScript 5 + - JavaScript + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/freeze +--- +
{{JSRef}}
+ +

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。

+ +
{{EmbedInteractiveExample("pages/js/object-freeze.html")}}
+ + + +

语法

+ +
Object.freeze(obj)
+ +

参数

+ +
+
obj
+
要被冻结的对象。
+
+ +

返回值

+ +

被冻结的对象。

+ +

描述

+ +

被冻结对象自身的所有属性都不可能以任何方式被修改。任何修改尝试都会失败,无论是静默地还是通过抛出{{jsxref("TypeError")}}异常(最常见但不仅限于{{jsxref("Strict_mode", "strict mode", "", 1)}})。

+ +

数据属性的值不可更改,访问器属性(有getter和setter)也同样(但由于是函数调用,给人的错觉是还是可以修改这个属性)。如果一个属性的值是个对象,则这个对象中的属性是可以修改的,除非它也是个冻结对象。数组作为一种对象,被冻结,其元素不能被修改。没有数组元素可以被添加或移除。

+ +

这个方法返回传递的对象,而不是创建一个被冻结的副本。

+ +

例子

+ +

冻结对象

+ +
var obj = {
+  prop: function() {},
+  foo: 'bar'
+};
+
+// 新的属性会被添加, 已存在的属性可能
+// 会被修改或移除
+obj.foo = 'baz';
+obj.lumpy = 'woof';
+delete obj.prop;
+
+// 作为参数传递的对象与返回的对象都被冻结
+// 所以不必保存返回的对象(因为两个对象全等)
+var o = Object.freeze(obj);
+
+o === obj; // true
+Object.isFrozen(obj); // === true
+
+// 现在任何改变都会失效
+obj.foo = 'quux'; // 静默地不做任何事
+// 静默地不添加此属性
+obj.quaxxor = 'the friendly duck';
+
+// 在严格模式,如此行为将抛出 TypeErrors
+function fail(){
+  'use strict';
+  obj.foo = 'sparky'; // throws a TypeError
+  delete obj.quaxxor; // 返回true,因为quaxxor属性从来未被添加
+  obj.sparky = 'arf'; // throws a TypeError
+}
+
+fail();
+
+// 试图通过 Object.defineProperty 更改属性
+// 下面两个语句都会抛出 TypeError.
+Object.defineProperty(obj, 'ohai', { value: 17 });
+Object.defineProperty(obj, 'foo', { value: 'eit' });
+
+// 也不能更改原型
+// 下面两个语句都会抛出 TypeError.
+Object.setPrototypeOf(obj, { x: 20 })
+obj.__proto__ = { x: 20 }
+ +

冻结数组

+ +
let a = [0];
+Object.freeze(a); // 现在数组不能被修改了.
+
+a[0]=1; // fails silently
+a.push(2); // fails silently
+
+// In strict mode such attempts will throw TypeErrors
+function fail() {
+  "use strict"
+  a[0] = 1;
+  a.push(2);
+}
+
+fail();
+ +

被冻结的对象是不可变的。但也不总是这样。下例展示了冻结对象不是常量对象(浅冻结)。

+ +
obj1 = {
+  internal: {}
+};
+
+Object.freeze(obj1);
+obj1.internal.a = 'aValue';
+
+obj1.internal.a // 'aValue'
+
+ +

对于一个常量对象,整个引用图(直接和间接引用其他对象)只能引用不可变的冻结对象。冻结的对象被认为是不可变的,因为整个对象中的整个对象状态(对其他对象的值和引用)是固定的。注意,字符串,数字和布尔总是不可变的,而函数和数组是对象。

+ +

要使对象不可变,需要递归冻结每个类型为对象的属性(深冻结)。当你知道对象在引用图中不包含任何  (循环引用)时,将根据你的设计逐个使用该模式,否则将触发无限循环。对 deepFreeze()  的增强将是具有接收路径(例如Array)参数的内部函数,以便当对象进入不变时,可以递归地调用 deepFreeze() 。你仍然有冻结不应冻结的对象的风险,例如[window]。

+ +
// 深冻结函数.
+function deepFreeze(obj) {
+
+  // 取回定义在obj上的属性名
+  var propNames = Object.getOwnPropertyNames(obj);
+
+  // 在冻结自身之前冻结属性
+  propNames.forEach(function(name) {
+    var prop = obj[name];
+
+    // 如果prop是个对象,冻结它
+    if (typeof prop == 'object' && prop !== null)
+      deepFreeze(prop);
+  });
+
+  // 冻结自身(no-op if already frozen)
+  return Object.freeze(obj);
+}
+
+obj2 = {
+  internal: {}
+};
+
+deepFreeze(obj2);
+obj2.internal.a = 'anotherValue';
+obj2.internal.a; // undefined
+
+ +

Notes

+ +

在ES5中,如果这个方法的参数不是一个对象(一个原始值),那么它会导致 {{jsxref("TypeError")}}。在ES2015中,非对象参数将被视为要被冻结的普通对象,并被简单地返回。

+ +
> Object.freeze(1)
+TypeError: 1 is not an object // ES5 code
+
+> Object.freeze(1)
+1                             // ES2015 code
+ +

对比 Object.seal()

+ +

Object.seal()密封的对象可以改变它们现有的属性。使用Object.freeze() 冻结的对象中现有属性是不可变的。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.9', 'Object.freeze')}}{{Spec2('ES5.1')}}Initial definition.
+ Implemented in JavaScript 1.8.5
{{SpecName('ES6', '#sec-object.freeze', 'Object.freeze')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-object.freeze', 'Object.freeze')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Object.freeze")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/fromentries/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/fromentries/index.html new file mode 100644 index 0000000000..80cb1de95a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/fromentries/index.html @@ -0,0 +1,105 @@ +--- +title: Object.fromEntries() +slug: Web/JavaScript/Reference/Global_Objects/Object/fromEntries +translation_of: Web/JavaScript/Reference/Global_Objects/Object/fromEntries +--- +
{{JSRef}}
+ +

 Object.fromEntries() 方法把键值对列表转换为一个对象。

+ +
{{EmbedInteractiveExample("pages/js/object-fromentries.html")}}
+ + + +

语法

+ +
Object.fromEntries(iterable);
+ +

参数

+ +
+
iterable
+
类似 {{jsxref("Array")}} 、 {{jsxref("Map")}} 或者其它实现了可迭代协议的可迭代对象。
+
+ +

返回值

+ +

一个由该迭代对象条目提供对应属性的新对象。

+ +

描述

+ +

Object.fromEntries() 方法接收一个键值对的列表参数,并返回一个带有这些键值对的新对象。这个迭代参数应该是一个能够实现@@iterator方法的的对象,返回一个迭代器对象。它生成一个具有两个元素的类数组的对象,第一个元素是将用作属性键的值,第二个元素是与该属性键关联的值。

+ +

Object.fromEntries() 执行与 {{jsxref("Object.entries")}} 互逆的操作。

+ +

示例

+ +

 Map 转化为 Object

+ +

通过 Object.fromEntries, 可以将 {{jsxref("Map")}} 转换为 {{jsxref("Object")}}:

+ +
const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
+const obj = Object.fromEntries(map);
+console.log(obj); // { foo: "bar", baz: 42 }
+
+ +

Array 转化为 Object

+ +

通过 Object.fromEntries, 可以将 {{jsxref("Array")}} 转换为 {{jsxref("Object")}}:

+ +
const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];
+const obj = Object.fromEntries(arr);
+console.log(obj); // { 0: "a", 1: "b", 2: "c" }
+
+ +

对象转换

+ +

Object.fromEntries 是与 {{jsxref("Object.entries()")}} 相反的方法,用 数组处理函数 可以像下面这样转换对象:

+ +
const object1 = { a: 1, b: 2, c: 3 };
+
+const object2 = Object.fromEntries(
+  Object.entries(object1)
+  .map(([ key, val ]) => [ key, val * 2 ])
+);
+
+console.log(object2);
+// { a: 2, b: 4, c: 6 }
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-object.fromentries', 'Object.fromEntries')}}{{Spec2('ESDraft')}}在 ECMAScript 2019 中首次被定义。
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.builtins.Object.fromEntries")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/getnotifier/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/getnotifier/index.html new file mode 100644 index 0000000000..fac0573de3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/getnotifier/index.html @@ -0,0 +1,93 @@ +--- +title: Object.getNotifier() +slug: Web/JavaScript/Reference/Global_Objects/Object/getNotifier +translation_of: Archive/Web/JavaScript/Object.getNotifier +--- +
{{JSRef}} {{obsolete_header}}
+ +

Object.getNotifer() 方法用于创建可人工触发 change 事件的对象,但该方法在浏览器中已被废弃。

+ +

语法

+ +
Object.getNotifier(obj)
+ +

参数

+ +
+
obj
+
获取通知的对象。
+
+ +

返回值

+ +

与传入对象相关联的通知对象。

+ +

描述

+ +

通知对象可触发 Object.observe() 所观察到的人工变动。

+ +

规范

+ +

Strawman proposal specification.

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("36")}} [1]{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("36")}} [1]{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
+
+ +

[1] Deprecated in Chrome 49.

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertydescriptor/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertydescriptor/index.html new file mode 100644 index 0000000000..a5b4088128 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertydescriptor/index.html @@ -0,0 +1,147 @@ +--- +title: Object.getOwnPropertyDescriptor() +slug: Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor +tags: + - JavaScript + - Object + - 对象 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor +--- +
{{JSRef}}
+ +

Object.getOwnPropertyDescriptor() 方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

+ +

{{EmbedInteractiveExample("pages/js/object-getownpropertydescriptor.html")}}

+ +

语法

+ +
Object.getOwnPropertyDescriptor(obj, prop)
+ +

参数

+ +
+
obj
+
需要查找的目标对象
+
prop
+
目标对象内属性名称
+
+ +

返回值

+ +

如果指定的属性存在于对象上,则返回其属性描述符对象(property descriptor),否则返回 {{jsxref("undefined")}}。

+ +

描述

+ +

该方法允许对一个属性的描述进行检索。在 Javascript 中, 属性 由一个字符串类型的“名字”(name)和一个“属性描述符”(property descriptor)对象构成。更多关于属性描述符类型以及他们属性的信息可以查看:{{jsxref("Object.defineProperty")}}.

+ +

一个属性描述符是一个记录,由下面属性当中的某些组成的:

+ +
+
value
+
该属性的值(仅针对数据属性描述符有效)
+
writable
+
当且仅当属性的值可以被改变时为true。(仅针对数据属性描述有效)
+
get
+
获取该属性的访问器函数(getter)。如果没有访问器, 该值为undefined。(仅针对包含访问器或设置器的属性描述有效)
+
set
+
获取该属性的设置器函数(setter)。 如果没有设置器, 该值为undefined。(仅针对包含访问器或设置器的属性描述有效)
+
configurable
+
当且仅当指定对象的属性描述可以被改变或者属性可被删除时,为true。
+
enumerable
+
当且仅当指定对象的属性可以被枚举出时,为 true
+
+ +

示例

+ +
var o, d;
+
+o = { get foo() { return 17; } };
+d = Object.getOwnPropertyDescriptor(o, "foo");
+// d {
+//   configurable: true,
+//   enumerable: true,
+//   get: /*the getter function*/,
+//   set: undefined
+// }
+
+o = { bar: 42 };
+d = Object.getOwnPropertyDescriptor(o, "bar");
+// d {
+//   configurable: true,
+//   enumerable: true,
+//   value: 42,
+//   writable: true
+// }
+
+o = {};
+Object.defineProperty(o, "baz", {
+  value: 8675309,
+  writable: false,
+  enumerable: false
+});
+d = Object.getOwnPropertyDescriptor(o, "baz");
+// d {
+//   value: 8675309,
+//   writable: false,
+//   enumerable: false,
+//   configurable: false
+// }
+ +

注意事项

+ +

在 ES5 中,如果该方法的第一个参数不是对象(而是原始类型),那么就会产生出现 {{jsxref("TypeError")}}。而在 ES2015,第一个的参数不是对象的话就会被强制转换为对象。

+ +
Object.getOwnPropertyDescriptor('foo', 0);
+// 类型错误: "foo" 不是一个对象  // ES5 code
+
+Object.getOwnPropertyDescriptor('foo', 0);
+// Object returned by ES2015 code: {
+//   configurable: false,
+//   enumerable: true,
+//   value: "f",
+//   writable: false
+// }
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态批注
{{SpecName('ES5.1', '#sec-15.2.3.3', 'Object.getOwnPropertyDescriptor')}}{{Spec2('ES5.1')}}Initial definition.
+ Implemented in JavaScript 1.8.5
{{SpecName('ES6', '#sec-object.getownpropertydescriptor', 'Object.getOwnPropertyDescriptor')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.getownpropertydescriptor', 'Object.getOwnPropertyDescriptor')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{Compat("javascript.builtins.Object.getOwnPropertyDescriptor")}}
+ +
+ +
+ +
相关链接 
+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertydescriptors/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertydescriptors/index.html new file mode 100644 index 0000000000..f07f3bfa33 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertydescriptors/index.html @@ -0,0 +1,87 @@ +--- +title: Object.getOwnPropertyDescriptors() +slug: Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors +translation_of: Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors +--- +
{{JSRef}}
+ +

Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符。

+ +

语法

+ +
Object.getOwnPropertyDescriptors(obj)
+ +

参数

+ +
+
obj
+
任意对象
+
+ +

返回值

+ +

所指定对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。

+ +
+
+ +

示例

+ +

浅拷贝一个对象

+ +

{{jsxref("Object.assign()")}} 方法只能拷贝源对象的可枚举的自身属性,同时拷贝时无法拷贝属性的特性们,而且访问器属性会被转换成数据属性,也无法拷贝源对象的原型,该方法配合 {{jsxref("Object.create()")}} 方法可以实现上面说的这些。

+ +
Object.create(
+  Object.getPrototypeOf(obj),
+  Object.getOwnPropertyDescriptors(obj)
+);
+
+ +

创建子类

+ +

创建子类的典型方法是定义子类,将其原型设置为超类的实例,然后在该实例上定义属性。这么写很不优雅,特别是对于 getters 和 setter 而言。 相反,您可以使用此代码设置原型:

+ +
function superclass() {}
+superclass.prototype = {
+  // 在这里定义方法和属性
+};
+function subclass() {}
+subclass.prototype = Object.create(superclass.prototype, Object.getOwnPropertyDescriptors({
+  // 在这里定义方法和属性
+}));
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-object.getownpropertydescriptors', 'Object.getOwnPropertyDescriptors')}}{{Spec2('ESDraft')}}Initial definition in ECMAScript 2017.
{{SpecName('ES2017', '#sec-object.getownpropertydescriptors', 'Object.getOwnPropertyDescriptors')}}{{Spec2('ES2017')}} 
+ +

浏览器兼容性

+ +
{{Compat("javascript.builtins.Object.getOwnPropertyDescriptors")}}
+ +
 
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertynames/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertynames/index.html new file mode 100644 index 0000000000..996a67689e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertynames/index.html @@ -0,0 +1,169 @@ +--- +title: Object.getOwnPropertyNames() +slug: Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames +tags: + - ECMAScript 5 + - JavaScript + - JavaScript 1.8.5 + - Method + - Object + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames +--- +
{{JSRef}}
+ +

Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。

+ +

语法

+ +
Object.getOwnPropertyNames(obj)
+ +

参数

+ +
+
obj
+
一个对象,其自身的可枚举和不可枚举属性的名称被返回。
+
+ +

返回值

+ +

在给定对象上找到的自身属性对应的字符串数组。

+ +

描述

+ +

Object.getOwnPropertyNames() 返回一个数组,该数组对元素是 obj自身拥有的枚举或不可枚举属性名称字符串。 数组中枚举属性的顺序与通过 {{jsxref("Statements/for...in", "for...in")}} 循环(或 {{jsxref("Object.keys")}})迭代该对象属性时一致。数组中不可枚举属性的顺序未定义。

+ +

示例

+ +

使用 Object.getOwnPropertyNames()

+ +
var arr = ["a", "b", "c"];
+console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
+
+// 类数组对象
+var obj = { 0: "a", 1: "b", 2: "c"};
+console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
+
+// 使用Array.forEach输出属性名和属性值
+Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
+  console.log(val + " -> " + obj[val]);
+});
+// 输出
+// 0 -> a
+// 1 -> b
+// 2 -> c
+
+//不可枚举属性
+var my_obj = Object.create({}, {
+  getFoo: {
+    value: function() { return this.foo; },
+    enumerable: false
+  }
+});
+my_obj.foo = 1;
+
+console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
+
+ +

如果你只要获取到可枚举属性,查看{{jsxref("Object.keys")}}或用{{jsxref("Statements/for...in", "for...in")}}循环(还会获取到原型链上的可枚举属性,不过可以使用{{jsxref("Object.prototype.hasOwnProperty()", "hasOwnProperty()")}}方法过滤掉)。

+ +

下面的例子演示了该方法不会获取到原型链上的属性:

+ +
function ParentClass() {}
+ParentClass.prototype.inheritedMethod = function() {};
+
+function ChildClass() {
+  this.prop = 5;
+  this.method = function() {};
+}
+
+ChildClass.prototype = new ParentClass;
+ChildClass.prototype.prototypeMethod = function() {};
+
+console.log(
+  Object.getOwnPropertyNames(
+    new ChildClass()  // ["prop", "method"]
+  )
+);
+
+ +

只获取不可枚举的属性

+ +

下面的例子使用了 {{jsxref("Array.prototype.filter()")}} 方法,从所有的属性名数组(使用Object.getOwnPropertyNames()方法获得)中去除可枚举的属性(使用{{jsxref("Object.keys()")}}方法获得),剩余的属性便是不可枚举的属性了:

+ +
var target = myObject;
+var enum_and_nonenum = Object.getOwnPropertyNames(target);
+var enum_only = Object.keys(target);
+var nonenum_only = enum_and_nonenum.filter(function(key) {
+    var indexInEnum = enum_only.indexOf(key);
+    if (indexInEnum == -1) {
+        // 没有发现在enum_only健集中意味着这个健是不可枚举的,
+        // 因此返回true 以便让它保持在过滤结果中
+        return true;
+    } else {
+        return false;
+    }
+});
+
+console.log(nonenum_only);
+ +
注:Array.filter(filt_func)方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
+ +

提示

+ +

在 ES5 中,如果参数不是一个原始对象类型,将抛出一个 {{jsxref("TypeError")}}  异常。在 ES2015 中,非对象参数被强制转换为对象 

+ +
Object.getOwnPropertyNames('foo');
+// TypeError: "foo" is not an object (ES5 code)
+
+Object.getOwnPropertyNames('foo');
+// ['length', '0', '1', '2']  (ES2015 code)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.4', 'Object.getOwnPropertyNames')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.8.5.
{{SpecName('ES6', '#sec-object.getownpropertynames', 'Object.getOwnPropertyNames')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-object.getownpropertynames', 'Object.getOwnPropertyNames')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.getOwnPropertyNames")}}

+ +

Firefox-specific notes

+ +

Firefox 28 {{geckoRelease("28")}}之前,Object.getOwnPropertyNames 不会获取到 {{jsxref("Error")}} 对象的属性。该 bug 在后面的版本修复了 ({{bug("724768")}})。

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertysymbols/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertysymbols/index.html new file mode 100644 index 0000000000..3ef6f41842 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/getownpropertysymbols/index.html @@ -0,0 +1,85 @@ +--- +title: Object.getOwnPropertySymbols() +slug: Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols +--- +
{{JSRef}}
+ +

Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有 Symbol 属性的数组。

+ +

语法

+ +
Object.getOwnPropertySymbols(obj)
+ +

参数

+ +
+
obj
+
要返回 Symbol 属性的对象。
+
+

返回值

+
+
在给定对象自身上找到的所有 Symbol 属性的数组。
+
+ +

描述

+ +

与{{jsxref("Object.getOwnPropertyNames()")}}类似,您可以将给定对象的所有符号属性作为 Symbol 数组获取。 请注意,{{jsxref("Object.getOwnPropertyNames()")}}本身不包含对象的 Symbol 属性,只包含字符串属性。

+ +

因为所有的对象在初始化的时候不会包含任何的 Symbol,除非你在对象上赋值了 Symbol 否则Object.getOwnPropertySymbols()只会返回一个空的数组。

+ +

示例

+ +
var obj = {};
+var a = Symbol("a");
+var b = Symbol.for("b");
+
+obj[a] = "localSymbol";
+obj[b] = "globalSymbol";
+
+var objectSymbols = Object.getOwnPropertySymbols(obj);
+
+console.log(objectSymbols.length); // 2
+console.log(objectSymbols)         // [Symbol(a), Symbol(b)]
+console.log(objectSymbols[0])      // Symbol(a)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-object.getownpropertysymbols', 'Object.getOwnPropertySymbols')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-object.getownpropertysymbols', 'Object.getOwnPropertySymbols')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.getOwnPropertySymbols")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/getprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/getprototypeof/index.html new file mode 100644 index 0000000000..e81cee9d3f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/getprototypeof/index.html @@ -0,0 +1,137 @@ +--- +title: Object.getPrototypeOf() +slug: Web/JavaScript/Reference/Global_Objects/Object/GetPrototypeOf +tags: + - ECMAScript 5 + - JavaScript + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf +--- +
{{JSRef}}
+ +

Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。

+ +

语法

+ +
Object.getPrototypeOf(object)
+
+ +
+
+

参数

+
+
obj
+
要返回其原型的对象。
+
+

返回值

+
+
给定对象的原型。如果没有继承属性,则返回 {{jsxref("null")}} 。
+
+ +

{{EmbedInteractiveExample("pages/js/object-getprototypeof.html")}}

+ +

示例

+ +
var proto = {};
+var obj = Object.create(proto);
+Object.getPrototypeOf(obj) === proto; // true
+
+var reg = /a/;
+Object.getPrototypeOf(reg) === RegExp.prototype; // true
+ +

说明

+ +
+

Object.getPrototypeOf(Object)  不是  Object.prototype

+
+ +
JavaScript中的 Object 是构造函数(创建对象的包装器)。
+一般用法是:
+var obj = new Object();
+
+所以:
+Object.getPrototypeOf( Object );               // ƒ () { [native code] }
+Object.getPrototypeOf( Function );             // ƒ () { [native code] }
+
+Object.getPrototypeOf( Object ) === Function.prototype;        // true
+
+Object.getPrototypeOf( Object )是把Object这一构造函数看作对象,
+返回的当然是函数对象的原型,也就是 Function.prototype。
+
+正确的方法是,Object.prototype是构造出来的对象的原型。
+var obj = new Object();
+Object.prototype === Object.getPrototypeOf( obj );              // true
+
+Object.prototype === Object.getPrototypeOf( {} );               // true
+ +
 
+ +
 
+ +
 
+ +

Notes

+ +

在 ES5 中,如果参数不是一个对象类型,将抛出一个{{jsxref("TypeError")}}异常。在 ES2015 中,参数会被强制转换为一个 {{jsxref("Object")}}

+ +
Object.getPrototypeOf('foo');
+// TypeError: "foo" is not an object (ES5 code)
+Object.getPrototypeOf('foo');
+// String.prototype                  (ES2015 code)
+ +
 
+ +
 
+ +
 
+ +
 
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.2', 'Object.getPrototypeOf')}}{{Spec2('ES5.1')}}Initial definition.
{{SpecName('ES6', '#sec-object.getprototypeof', 'Object.getPrototypeOf')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-object.getprototypeof', 'Object.getPrototypeOf')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.getPrototypeOf")}}

+ +

Opera 特别提示

+ +

即使旧版本Opera不支持Object.getPrototypeOf(),Opera 10.50之后还支持非标准的 {{jsxref("Object.proto", "__proto__")}}属性。

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/hasownproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/hasownproperty/index.html new file mode 100644 index 0000000000..70f5f307d6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/hasownproperty/index.html @@ -0,0 +1,168 @@ +--- +title: Object.prototype.hasOwnProperty() +slug: Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty +tags: + - JavaScript + - Method + - Object + - Prototype + - 原型 + - 对象 + - 属性 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty +--- +
{{JSRef}}
+ +

hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。

+ +
{{EmbedInteractiveExample("pages/js/object-prototype-hasownproperty.html")}}
+ + + +

语法

+ +
obj.hasOwnProperty(prop)
+ +

参数

+ +
+
prop
+
要检测的属性的 {{jsxref("String")}} 字符串形式表示的名称,或者 {{jsxref("Symbol")}}。
+
+ +

返回值

+ +

用来判断某个对象是否含有指定的属性的布尔值 {{jsxref("Boolean")}}。

+ +

描述

+ +

所有继承了 {{jsxref("Object")}} 的对象都会继承到 hasOwnProperty 方法。这个方法可以用来检测一个对象是否含有特定的自身属性;和 {{jsxref("Operators/in", "in")}} 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。

+ +

备注

+ +

即使属性的值是 nullundefined,只要属性存在,hasOwnProperty 依旧会返回 true

+ +
o = new Object();
+o.propOne = null;
+o.hasOwnProperty('propOne'); // 返回 true
+o.propTwo = undefined;
+o.hasOwnProperty('propTwo'); // 返回 true
+
+ +

示例

+ +

使用 hasOwnProperty 方法判断属性是否存在

+ +

下面的例子检测了对象 o 是否含有自身属性 prop

+ +
o = new Object();
+o.hasOwnProperty('prop'); // 返回 false
+o.prop = 'exists';
+o.hasOwnProperty('prop'); // 返回 true
+delete o.prop;
+o.hasOwnProperty('prop'); // 返回 false
+
+ +

自身属性与继承属性

+ +

下面的例子演示了 hasOwnProperty 方法对待自身属性和继承属性的区别:

+ +
o = new Object();
+o.prop = 'exists';
+o.hasOwnProperty('prop');             // 返回 true
+o.hasOwnProperty('toString');         // 返回 false
+o.hasOwnProperty('hasOwnProperty');   // 返回 false
+
+ +

遍历一个对象的所有自身属性

+ +

下面的例子演示了如何在遍历一个对象的所有属性时忽略掉继承属性,注意这里 {{jsxref("Statements/for...in", "for...in")}}  循环只会遍历可枚举属性,所以不应该基于这个循环中没有不可枚举的属性而得出 hasOwnProperty 是严格限制于可枚举项目的(如同 {{jsxref("Object.getOwnPropertyNames()")}})。

+ +
var buz = {
+  fog: 'stack'
+};
+
+for (var name in buz) {
+  if (buz.hasOwnProperty(name)) {
+    console.log('this is fog (' +
+      name + ') for sure. Value: ' + buz[name]);
+  }
+  else {
+    console.log(name); // toString or something else
+  }
+}
+
+ +

使用 hasOwnProperty 作为属性名

+ +

JavaScript 并没有保护 hasOwnProperty 这个属性名,因此,当某个对象可能自有一个占用该属性名的属性时,就需要使用外部的 hasOwnProperty 获得正确的结果:

+ +
var foo = {
+  hasOwnProperty: function() {
+    return false;
+  },
+  bar: 'Here be dragons'
+};
+
+foo.hasOwnProperty('bar'); // 始终返回 false
+
+// 如果担心这种情况,
+// 可以直接使用原型链上真正的 hasOwnProperty 方法
+({}).hasOwnProperty.call(foo, 'bar'); // true
+
+// 也可以使用 Object 原型上的 hasOwnProperty 属性
+Object.prototype.hasOwnProperty.call(foo, 'bar'); // true
+
+ +

注意,只有在最后一种情况下,才不会新建任何对象。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-object.prototype.hasownproperty', 'Object.prototype.hasOwnProperty')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-object.prototype.hasownproperty', 'Object.prototype.hasOwnProperty')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-15.2.4.5', 'Object.prototype.hasOwnProperty')}}{{Spec2('ES5.1')}}
{{SpecName('ES3')}}{{Spec2('ES3')}}最开始在JavaScript 1.5实现。
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Object.hasOwnProperty")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/index.html new file mode 100644 index 0000000000..1cfeb4d57c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/index.html @@ -0,0 +1,183 @@ +--- +title: Object +slug: Web/JavaScript/Reference/Global_Objects/Object +tags: + - Constructor + - JavaScript + - Object + - 对象 + - 构造器 +translation_of: Web/JavaScript/Reference/Global_Objects/Object +--- +
{{JSRef}}
+ +

Object 构造函数创建一个对象包装器。

+ +

语法

+ +
// 对象初始化器(Object initialiser)或对象字面量(literal)
+{ [ nameValuePair1[, nameValuePair2[, ...nameValuePairN] ] ] }
+
+// 以构造函数形式来调用
+new Object([value])
+ +

参数

+ +
+
nameValuePair1, nameValuePair2, ... nameValuePairN
+
成对的名称(字符串)与值(任何值),其中名称通过冒号与值分隔。
+
value
+
任何值。
+
+ +

描述

+ +

在JavaScript中,几乎所有的对象都是Object类型的实例,它们都会从Object.prototype继承属性和方法。Object 构造函数为给定值创建一个对象包装器。Object构造函数,会根据给定的参数创建对象,具体有以下情况:

+ + + +

当以非构造函数形式被调用时,Object 的行为等同于 new Object()

+ +

可查看 对象初始化/字面量语法

+ +

Object 构造函数的属性

+ +
+
Object.length
+
值为 1。
+
+ +
+
{{jsxref("Object.prototype")}}
+
可以为所有 Object 类型的对象添加属性。
+
+ +

Object 构造函数的方法

+ +
+
{{jsxref("Object.assign()")}}
+
通过复制一个或多个对象来创建一个新的对象。
+
{{jsxref("Object.create()")}}
+
使用指定的原型对象和属性创建一个新对象。
+
{{jsxref("Object.defineProperty()")}}
+
给对象添加一个属性并指定该属性的配置。
+
{{jsxref("Object.defineProperties()")}}
+
给对象添加多个属性并分别指定它们的配置。
+
{{jsxref("Object.entries()")}}
+
返回给定对象自身可枚举属性的 [key, value] 数组。
+
{{jsxref("Object.freeze()")}}
+
冻结对象:其他代码不能删除或更改任何属性。
+
{{jsxref("Object.getOwnPropertyDescriptor()")}}
+
返回对象指定的属性配置。
+
{{jsxref("Object.getOwnPropertyNames()")}}
+
返回一个数组,它包含了指定对象所有的可枚举或不可枚举的属性名。
+
{{jsxref("Object.getOwnPropertySymbols()")}}
+
返回一个数组,它包含了指定对象自身所有的符号属性。
+
{{jsxref("Object.getPrototypeOf()")}}
+
返回指定对象的原型对象。
+
{{jsxref("Object.is()")}}
+
比较两个值是否相同。所有 NaN 值都相等(这与==和===不同)。
+
{{jsxref("Object.isExtensible()")}}
+
判断对象是否可扩展。
+
{{jsxref("Object.isFrozen()")}}
+
判断对象是否已经冻结。
+
{{jsxref("Object.isSealed()")}}
+
判断对象是否已经密封。
+
{{jsxref("Object.keys()")}}
+
返回一个包含所有给定对象自身可枚举属性名称的数组。
+
{{jsxref("Object.preventExtensions()")}}
+
防止对象的任何扩展。
+
{{jsxref("Object.seal()")}}
+
防止其他代码删除对象的属性。
+
{{jsxref("Object.setPrototypeOf()")}}
+
设置对象的原型(即内部 [[Prototype]] 属性)。
+
{{jsxref("Object.values()")}}
+
返回给定对象自身可枚举值的数组。
+
+ +

Object 实例和 Object 原型对象

+ +

JavaScript中的所有对象都来自 Object;所有对象从{{jsxref("Object.prototype")}}继承方法和属性,尽管它们可能被覆盖。例如,其他构造函数的原型将覆盖 constructor 属性并提供自己的 toString() 方法。Object 原型对象的更改将传播到所有对象,除非受到这些更改的属性和方法将沿原型链进一步覆盖。

+ +

属性

+ +
{{ page('zh-CN/docs/JavaScript/Reference/Global_Objects/Object/prototype', 'Properties') }}
+ +

方法

+ +
{{ page('zh-CN/docs/JavaScript/Reference/Global_Objects/Object/prototype', 'Methods') }}
+ +

示例

+ +

给定 undefinednull 类型使用 Object

+ +

下面的例子将一个空的 Object 对象存到 o 中:

+ +
var o = new Object();
+
+ +
var o = new Object(undefined);
+
+ +
var o = new Object(null);
+
+ +

使用 Object 生成布尔对象

+ +

下面的例子将{{jsxref("Boolean")}} 对象存到 o 中:

+ +
// 等价于 o = new Boolean(true);
+var o = new Object(true);
+
+ +
// 等价于 o = new Boolean(false);
+var o = new Object(Boolean());
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.2', 'Object')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-object-objects', 'Object')}}{{Spec2('ES6')}}Added Object.assign, Object.getOwnPropertySymbols, Object.setPrototypeOf, Object.is
{{SpecName('ESDraft', '#sec-object-objects', 'Object')}}{{Spec2('ESDraft')}}Added Object.entries and Object.values.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/is/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/is/index.html new file mode 100644 index 0000000000..ed905858d9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/is/index.html @@ -0,0 +1,150 @@ +--- +title: Object.is() +slug: Web/JavaScript/Reference/Global_Objects/Object/is +tags: + - ECMAScript 2015 + - JavaScript + - 判断 + - 对象 + - 方法 + - 相等 +translation_of: Web/JavaScript/Reference/Global_Objects/Object/is +--- +
{{JSRef}}
+ +

Object.is() 方法判断两个值是否为同一个值

+ +

语法

+ +

+

Object.is(value1, value2);
+ + +

参数

+ +
+
value1
+
被比较的第一个值。
+
value2
+
被比较的第二个值。
+
+ +

返回值

+ +

一个 {{jsxref("Boolean")}} 类型标示两个参数是否是同一个值。

+ +

描述

+ +

Object.is() 方法判断两个值是否为同一个值。如果满足以下条件则两个值相等:

+ + + +

与{{jsxref("Operators/Comparison_Operators", "==", "#Equality")}} 运算不同。  == 运算符在判断相等前对两边的变量(如果它们不是同一类型) 进行强制转换 (这种行为的结果会将 "" == false 判断为 true), 而 Object.is不会强制转换两边的值。

+ +

与{{jsxref("Operators/Comparison_Operators", "===", "#Identity")}} 运算也不相同。 === 运算符 (也包括 == 运算符) 将数字 -0 和 +0 视为相等 ,而将{{jsxref("Number.NaN")}} 与{{jsxref("NaN")}}视为不相等.

+ +

Polyfill

+ +
if (!Object.is) {
+  Object.is = function(x, y) {
+    // SameValue algorithm
+    if (x === y) { // Steps 1-5, 7-10
+      // Steps 6.b-6.e: +0 != -0
+      return x !== 0 || 1 / x === 1 / y;
+    } else {
+      // Step 6.a: NaN == NaN
+      return x !== x && y !== y;
+    }
+  };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-object.is', 'Object.is')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-object.is', 'Object.is')}}{{Spec2('ESDraft')}}
+ +

例子

+ +

使用 Object.is

+ +
Object.is('foo', 'foo');     // true
+Object.is(window, window);   // true
+
+Object.is('foo', 'bar');     // false
+Object.is([], []);           // false
+
+var foo = { a: 1 };
+var bar = { a: 1 };
+Object.is(foo, foo);         // true
+Object.is(foo, bar);         // false
+
+Object.is(null, null);       // true
+
+// 特例
+Object.is(0, -0);            // false
+Object.is(0, +0);            // true
+Object.is(-0, -0);           // true
+Object.is(NaN, 0/0);         // true
+
+ +

规范

+ +

+

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-object.is', 'Object.is')}}
+  
+ + +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Object.is")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/isextensible/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/isextensible/index.html new file mode 100644 index 0000000000..c168d98bfd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/isextensible/index.html @@ -0,0 +1,144 @@ +--- +title: Object.isExtensible() +slug: Web/JavaScript/Reference/Global_Objects/Object/isExtensible +translation_of: Web/JavaScript/Reference/Global_Objects/Object/isExtensible +--- +
{{JSRef("Global_Objects", "Object")}}
+ +

概述

+ +

Object.isExtensible() 方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。

+ +

语法

+ +
Object.isExtensible(obj)
+ +

参数

+ +
+
obj
+
需要检测的对象
+
+ +

返回值

+ +

    表示给定对象是否可扩展的一个Boolean 。

+ +

描述

+ +

默认情况下,对象是可扩展的:即可以为他们添加新的属性。以及它们的 {{jsxref("Object.proto", "__proto__")}}{{deprecated_inline}} 属性可以被更改。{{jsxref("Object.preventExtensions")}},{{jsxref("Object.seal")}} 或 {{jsxref("Object.freeze")}} 方法都可以标记一个对象为不可扩展(non-extensible)。

+ +

例子

+ +
// 新对象默认是可扩展的.
+var empty = {};
+Object.isExtensible(empty); // === true
+
+// ...可以变的不可扩展.
+Object.preventExtensions(empty);
+Object.isExtensible(empty); // === false
+
+// 密封对象是不可扩展的.
+var sealed = Object.seal({});
+Object.isExtensible(sealed); // === false
+
+// 冻结对象也是不可扩展.
+var frozen = Object.freeze({});
+Object.isExtensible(frozen); // === false
+
+ +

 

+ +

注意

+ +

在 ES5 中,如果参数不是一个对象类型,将抛出一个 {{jsxref("TypeError")}} 异常。在 ES6 中, non-object 参数将被视为一个不可扩展的普通对象,因此会返回 false 。

+ +
Object.isExtensible(1);
+// TypeError: 1 is not an object (ES5 code)
+
+Object.isExtensible(1);
+// false                         (ES6 code)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.13', 'Object.isExtensible')}}{{Spec2('ES5.1')}}Initial definition.
+ Implemented in JavaScript 1.8.5
{{SpecName('ES6', '#sec-object.isextensible', 'Object.isExtensible')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support4 (2.0)69125.1
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureFirefox Mobile (Gecko)AndroidIE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/isfrozen/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/isfrozen/index.html new file mode 100644 index 0000000000..5ab6d88862 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/isfrozen/index.html @@ -0,0 +1,153 @@ +--- +title: Object.isFrozen() +slug: Web/JavaScript/Reference/Global_Objects/Object/isFrozen +tags: + - ECMAScript 5 + - JavaScript + - JavaScript 1.8.5 + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/isFrozen +--- +
{{JSRef}}
+ +

Object.isFrozen()方法判断一个对象是否被{{jsxref("Object.freeze()", "冻结", "", 1)}}。

+ +

语法

+ +
Object.isFrozen(obj)
+ +

参数

+ +
+
obj
+
被检测的对象。
+
+

返回值

+
+
表示给定对象是否被冻结的{{jsxref("Boolean")}}。
+
+ +

描述

+ +

一个对象是冻结的是指它不可{{jsxref("Object.isExtensible", "扩展")}},所有属性都是不可配置的,且所有数据属性(即没有getter或setter组件的访问器的属性)都是不可写的。

+ +

例子

+ +
// 一个对象默认是可扩展的,所以它也是非冻结的.
+Object.isFrozen({}); // === false
+
+// 一个不可扩展的空对象同时也是一个冻结对象.
+var vacuouslyFrozen = Object.preventExtensions({});
+Object.isFrozen(vacuouslyFrozen) //=== true;
+
+// 一个非空对象默认也是非冻结的.
+var oneProp = { p: 42 };
+Object.isFrozen(oneProp) //=== false
+
+// 让这个对象变的不可扩展,并不意味着这个对象变成了冻结对象,
+// 因为p属性仍然是可以配置的(而且可写的).
+Object.preventExtensions(oneProp);
+Object.isFrozen(oneProp) //=== false
+
+// 此时,如果删除了这个属性,则它会成为一个冻结对象.
+delete oneProp.p;
+Object.isFrozen(oneProp) //=== true
+
+// 一个不可扩展的对象,拥有一个不可写但可配置的属性,则它仍然是非冻结的.
+var nonWritable = { e: "plep" };
+Object.preventExtensions(nonWritable);
+Object.defineProperty(nonWritable, "e", { writable: false }); // 变得不可写
+Object.isFrozen(nonWritable) //=== false
+
+// 把这个属性改为不可配置,会让这个对象成为冻结对象.
+Object.defineProperty(nonWritable, "e", { configurable: false }); // 变得不可配置
+Object.isFrozen(nonWritable) //=== true
+
+// 一个不可扩展的对象,拥有一个不可配置但可写的属性,则它仍然是非冻结的.
+var nonConfigurable = { release: "the kraken!" };
+Object.preventExtensions(nonConfigurable);
+Object.defineProperty(nonConfigurable, "release", { configurable: false });
+Object.isFrozen(nonConfigurable) //=== false
+
+// 把这个属性改为不可写,会让这个对象成为冻结对象.
+Object.defineProperty(nonConfigurable, "release", { writable: false });
+Object.isFrozen(nonConfigurable) //=== true
+
+// 一个不可扩展的对象,值拥有一个访问器属性,则它仍然是非冻结的.
+var accessor = { get food() { return "yum"; } };
+Object.preventExtensions(accessor);
+Object.isFrozen(accessor) //=== false
+
+// ...但把这个属性改为不可配置,会让这个对象成为冻结对象.
+Object.defineProperty(accessor, "food", { configurable: false });
+Object.isFrozen(accessor) //=== true
+
+// 使用Object.freeze是冻结一个对象最方便的方法.
+var frozen = { 1: 81 };
+Object.isFrozen(frozen) //=== false
+Object.freeze(frozen);
+Object.isFrozen(frozen) //=== true
+
+// 一个冻结对象也是一个密封对象.
+Object.isSealed(frozen) //=== true
+
+// 当然,更是一个不可扩展的对象.
+Object.isExtensible(frozen) //=== false
+
+
+ +

注意

+ +

在 ES5 中,如果参数不是一个对象类型,将抛出一个{{jsxref("TypeError")}}异常。在 ES2015 中,非对象参数将被视为一个冻结的普通对象,因此会返回true

+ +
Object.isFrozen(1);
+// TypeError: 1 is not an object (ES5 code)
+
+Object.isFrozen(1);
+// true                          (ES2015 code)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.12', 'Object.isFrozen')}}{{Spec2('ES5.1')}}Initial definition.
+ Implemented in JavaScript 1.8.5
{{SpecName('ES6', '#sec-object.isfrozen', 'Object.isFrozen')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.isfrozen', 'Object.isFrozen')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.isFrozen")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/isprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/isprototypeof/index.html new file mode 100644 index 0000000000..84ce38e934 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/isprototypeof/index.html @@ -0,0 +1,171 @@ +--- +title: Object.prototype.isPrototypeOf() +slug: Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf +tags: + - JavaScript + - Object + - Prototype + - isPrototypeOf() + - 原型 + - 对象 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf +--- +
{{JSRef}}
+ +

isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。

+ +
+

isPrototypeOf() 与 {{jsxref("Operators/instanceof", "instanceof")}} 运算符不同。在表达式 "object instanceof AFunction"中,object 的原型链是针对 AFunction.prototype 进行检查的,而不是针对 AFunction 本身。

+
+ +

语法

+ +
prototypeObj.isPrototypeOf(object)
+ +

参数

+ +
+
object
+
在该对象的原型链上搜寻
+
+ +

返回值

+ +

{{jsxref("Boolean")}},表示调用对象是否在另一个对象的原型链上。

+ +

报错

+ +
+
{{jsxref("TypeError")}}
+
如果 prototypeObj 为 undefined 或 null,会抛出 {{jsxref("TypeError")}}。
+
+ +

描述

+ +

isPrototypeOf() 方法允许你检查一个对象是否存在于另一个对象的原型链上。

+ +

示例

+ +

本示例展示了 Baz.prototype, Bar.prototypeFoo.prototype 和 Object.prototypebaz 对象的原型链上:

+ +
function Foo() {}
+function Bar() {}
+function Baz() {}
+
+Bar.prototype = Object.create(Foo.prototype);
+Baz.prototype = Object.create(Bar.prototype);
+
+var baz = new Baz();
+
+console.log(Baz.prototype.isPrototypeOf(baz)); // true
+console.log(Bar.prototype.isPrototypeOf(baz)); // true
+console.log(Foo.prototype.isPrototypeOf(baz)); // true
+console.log(Object.prototype.isPrototypeOf(baz)); // true
+
+ +

如果你有段代码只在需要操作继承自一个特定的原型链的对象的情况下执行,同 {{jsxref("Operators/instanceof", "instanceof")}} 操作符一样 isPrototypeOf() 方法就会派上用场,例如,为了确保某些方法或属性将位于对象上。

+ +

例如,检查 baz 对象是否继承自 Foo.prototype

+ +
if (Foo.prototype.isPrototypeOf(baz)) {
+  // do something safe
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES3')}}{{Spec2('ES3')}}初始定义
{{SpecName('ES5.1', '#sec-15.2.4.5', 'Object.prototype.hasOwnProperty')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-object.prototype.hasownproperty', 'Object.prototype.hasOwnProperty')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-object.prototype.hasownproperty', 'Object.prototype.hasOwnProperty')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + +
特性ChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
基础支持{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础支持{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/issealed/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/issealed/index.html new file mode 100644 index 0000000000..df91848da8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/issealed/index.html @@ -0,0 +1,124 @@ +--- +title: Object.isSealed() +slug: Web/JavaScript/Reference/Global_Objects/Object/isSealed +tags: + - ECMAScript5 + - JavaScript + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/isSealed +--- +
{{JSRef}}
+ +

Object.isSealed() 方法判断一个对象是否被密封。

+ +

语法

+ +
Object.isSealed(obj)
+ +

参数

+ +
+
obj
+
要被检查的对象。
+
+ +

返回值

+ +

表示给定对象是否被密封的一个{{jsxref("Boolean")}} 。

+ +

描述

+ +

如果这个对象是密封的,则返回 true,否则返回 false。密封对象是指那些不可 {{jsxref("Object.isExtensible", "扩展")}} 的,且所有自身属性都不可配置且因此不可删除(但不一定是不可写)的对象。

+ +

例子

+ +
// 新建的对象默认不是密封的.
+var empty = {};
+Object.isSealed(empty); // === false
+
+// 如果你把一个空对象变的不可扩展,则它同时也会变成个密封对象.
+Object.preventExtensions(empty);
+Object.isSealed(empty); // === true
+
+// 但如果这个对象不是空对象,则它不会变成密封对象,因为密封对象的所有自身属性必须是不可配置的.
+var hasProp = { fee: "fie foe fum" };
+Object.preventExtensions(hasProp);
+Object.isSealed(hasProp); // === false
+
+// 如果把这个属性变的不可配置,则这个属性也就成了密封对象.
+Object.defineProperty(hasProp, "fee", { configurable: false });
+Object.isSealed(hasProp); // === false
+Object.isSealed(hasProp.fee); // === true
+
+// 最简单的方法来生成一个密封对象,当然是使用Object.seal.
+var sealed = {};
+Object.seal(sealed);
+Object.isSealed(sealed); // === true
+
+// 一个密封对象同时也是不可扩展的.
+Object.isExtensible(sealed); // === false
+
+// 一个密封对象也可以是一个冻结对象,但不是必须的.
+Object.isFrozen(sealed); // === true ,所有的属性都是不可写的
+var s2 = Object.seal({ p: 3 });
+Object.isFrozen(s2); // === false, 属性"p"可写
+
+var s3 = Object.seal({ get p() { return 0; } });
+Object.isFrozen(s3); // === true ,访问器属性不考虑可写不可写,只考虑是否可配置
+ +

注意

+ +

在ES5中,如果这个方法的参数不是一个对象(一个原始类型),那么它会导致{{jsxref("TypeError")}}。在ES2015中,非对象参数将被视为是一个密封的普通对象,只返回true

+ +
Object.isSealed(1);
+// TypeError: 1 is not an object (ES5 code)
+
+Object.isSealed(1);
+// true                          (ES2015 code)
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.11', 'Object.isSealed')}}{{Spec2('ES5.1')}}Initial definition.
+ Implemented in JavaScript 1.8.5
{{SpecName('ES6', '#sec-object.issealed', 'Object.isSealed')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.issealed', 'Object.isSealed')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.isSealed")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/keys/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/keys/index.html new file mode 100644 index 0000000000..b477b88320 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/keys/index.html @@ -0,0 +1,158 @@ +--- +title: Object.keys() +slug: Web/JavaScript/Reference/Global_Objects/Object/keys +tags: + - 'CCAC: Chrome Console Auto Copy' + - ECMAScript 5 + - JavaScript + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/keys +--- +

{{JSRef}}

+ +

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。

+ +

语法

+ +
Object.keys(obj)
+ +

参数

+ +
+
obj
+
要返回其枚举自身属性的对象。
+
+ +

返回值

+ +

一个表示给定对象的所有可枚举属性的字符串数组。

+ +

描述

+ +

Object.keys 返回一个所有元素为字符串的数组,其元素来自于从给定的object上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致。

+ +

例子

+ +
// simple array
+var arr = ['a', 'b', 'c'];
+console.log(Object.keys(arr)); // console: ['0', '1', '2']
+
+// array like object
+var obj = { 0: 'a', 1: 'b', 2: 'c' };
+console.log(Object.keys(obj)); // console: ['0', '1', '2']
+
+// array like object with random key ordering
+var anObj = { 100: 'a', 2: 'b', 7: 'c' };
+console.log(Object.keys(anObj)); // console: ['2', '7', '100']
+
+// getFoo is a property which isn't enumerable
+var myObj = Object.create({}, {
+  getFoo: {
+    value: function () { return this.foo; }
+  }
+});
+myObj.foo = 1;
+console.log(Object.keys(myObj)); // console: ['foo']
+ +

如果你想获取一个对象的所有属性,,甚至包括不可枚举的,请查看{{jsxref("Object.getOwnPropertyNames")}}。

+ +

注意

+ +

在ES5里,如果此方法的参数不是对象(而是一个原始值),那么它会抛出 TypeError。在ES2015中,非对象的参数将被强制转换为一个对象。

+ +
Object.keys("foo");
+// TypeError: "foo" is not an object (ES5 code)
+
+Object.keys("foo");
+// ["0", "1", "2"]                   (ES2015 code)
+ +

Polyfill

+ +

要在原生不支持的旧环境中添加兼容的Object.keys,请复制以下代码段:

+ +
if (!Object.keys) {
+  Object.keys = (function () {
+    var hasOwnProperty = Object.prototype.hasOwnProperty,
+        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
+        dontEnums = [
+          'toString',
+          'toLocaleString',
+          'valueOf',
+          'hasOwnProperty',
+          'isPrototypeOf',
+          'propertyIsEnumerable',
+          'constructor'
+        ],
+        dontEnumsLength = dontEnums.length;
+
+    return function (obj) {
+      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
+
+      var result = [];
+
+      for (var prop in obj) {
+        if (hasOwnProperty.call(obj, prop)) result.push(prop);
+      }
+
+      if (hasDontEnumBug) {
+        for (var i=0; i < dontEnumsLength; i++) {
+          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
+        }
+      }
+      return result;
+    }
+  })()
+};
+
+ +

上面的代码在IE7(也许IE8也是)下有个问题,就是如果传入一个来自其他 window 对象下的对象时,不可枚举的属性也会获取到。

+ +

另一个简单的实现,参见Javascript - Object.keys Browser Compatibility

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.14', 'Object.keys')}}{{Spec2('ES5.1')}}Initial definition.
+ Implemented in JavaScript 1.8.5
{{SpecName('ES6', '#sec-object.keys', 'Object.keys')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.keys', 'Object.keys')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.builtins.Object.keys")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/nosuchmethod/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/nosuchmethod/index.html new file mode 100644 index 0000000000..7b54198c19 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/nosuchmethod/index.html @@ -0,0 +1,208 @@ +--- +title: Object.prototype.__noSuchMethod__ +slug: Web/JavaScript/Reference/Global_Objects/Object/noSuchMethod +translation_of: Archive/Web/JavaScript/Object.noSuchMethod +--- +
{{JSRef}} {{obsolete_header}}
+ +

__noSuchMethod__ 属性曾经是指当调用某个对象里不存在的方法时即将被执行的函数,但是现在这个函数已经不可用。

+ +

__noSuchMethod__ 属性被移除之后,ECMAScript 2015 (ES6) 规范转而采用 {{jsxref("Proxy")}} 对象, 可以实现下面的效果(以及更多)。

+ +

语法

+ +
obj.__noSuchMethod__ = fun
+ +

参数

+ +
+
fun
+
函数形式如下:
+
+
function (id, args) { . . . }
+ +
+
id
+
调用的不存在的方法名
+
args
+
传递给该方法的参数数组
+
+
+
+ +

描述

+ +

默认情况喜爱,试图调用对象上不存在的方法其结果是在{{jsxref("TypeError")}}上抛出异常,这种行为可以在

+ +

By default, an attempt to call a method that doesn't exist on an object results in a {{jsxref("TypeError")}} being thrown. This behavior can be circumvented by defining a function at that object's __noSuchMethod__ member. The function takes two arguments, the first is the name of the method attempted and the second is an array of the arguments that were passed in the method call. The second argument is an actual array (that is, it inherits through the {{jsxref("Array.prototype")}} chain) and not the array-like arguments object.

+ +

If this method cannot be called, either as if undefined by default, if deleted, or if manually set to a non-function, the JavaScript engine will revert to throwing TypeErrors.

+ +

Examples

+ +

Simple test of __noSuchMethod__

+ +
var o = {
+  __noSuchMethod__: function(id, args) {
+                      console.log(id, '(' + args.join(', ') + ')');
+                    }
+};
+
+o.foo(1, 2, 3);
+o.bar(4, 5);
+o.baz();
+
+// Output
+// foo (1, 2, 3)
+// bar (4, 5)
+// baz ()
+
+ +

Using __noSuchMethod__ to simulate multiple inheritance

+ +

An example of code that implements a primitive form of multiple inheritance is shown below.

+ +
// Doesn't work with multiple inheritance objects as parents
+function noMethod(name, args) {
+  var parents = this.__parents_;
+
+  // Go through all parents
+  for (var i = 0; i < parents.length; i++) {
+    // If we find a function on the parent, we call it
+    if (typeof parents[i][name] == "function") {
+      return parents[i][name].apply(this, args);
+    }
+  }
+
+  // If we get here, the method hasn't been found
+  throw new TypeError;
+}
+
+// Used to add a parent for multiple inheritance
+function addParent(obj, parent) {
+  // If the object isn't initialized, initialize it
+  if (!obj.__parents_) {
+    obj.__parents_ = [];
+    obj.__noSuchMethod__ = noMethod;
+  }
+
+  // Add the parent
+  obj.__parents_.push(parent);
+}
+
+ +

An example of using this idea is shown below.

+ +
// Example base class 1
+function NamedThing(name){
+  this.name=name;
+}
+
+NamedThing.prototype = {
+  getName: function() { return this.name; },
+  setName: function(newName) { this.name = newName; }
+}
+
+// Example base class 2
+function AgedThing(age) {
+  this.age = age;
+}
+
+AgedThing.prototype = {
+  getAge: function() { return this.age; },
+  setAge: function(age) { this.age = age; }
+}
+
+// Child class. inherits from NamedThing and AgedThing
+// as well as defining address
+function Person(name, age, address){
+  addParent(this, NamedThing.prototype);
+  NamedThing.call(this, name);
+  addParent(this, AgedThing.prototype);
+  AgedThing.call(this, age);
+  this.address = address;
+}
+
+Person.prototype = {
+  getAddr: function() { return this.address; },
+  setAddr: function(addr) { this.address = addr; }
+}
+
+var bob = new Person("bob", 25, "New York");
+
+console.log("getAge is " + (("getAge" in bob) ? "in" : "not in") + " bob");
+// getAge is not in bob
+
+console.log("bob's age is: " + bob.getAge());
+// bob's age is: 25
+
+console.log("getName is " + (("getName" in bob) ? "in" : "not in") + " bob");
+// getName is not in bob
+
+console.log("bob's name is: " + bob.getName());
+// bob's name is: bob
+
+console.log("getAddr is " + (("getAddr" in bob) ? "in" : "not in") + " bob");
+// getAddr is in bob
+
+console.log("bob's address is: " + bob.getAddr());
+// bob's address is: New York
+
+ +

Specifications

+ +

Not part of any specifications. This feature has been removed, see {{bug(683218)}}.

+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}} [1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}} [1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] This feature was implemented until version 43.

diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/object/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/object/index.html new file mode 100644 index 0000000000..ded4dfae16 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/object/index.html @@ -0,0 +1,80 @@ +--- +title: Object() 构造函数 +slug: Web/JavaScript/Reference/Global_Objects/Object/Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/Object +--- +
{{JSRef}}
+ +

Object 构造函数将给定的值包装为一个新对象。

+ + + +

在非构造函数上下文中调用时, Object 和 new Object()表现一致。

+ +

语法

+ +
new Object()
+new Object(value)
+ +

参数

+ +
+
value
+
任意值
+
+ +

例子

+ +

创建一个新对象

+ +
let o = new Object()
+o.foo = 42
+
+console.log(o)
+// Object { foo: 42 }
+
+ +

使用 Object 创建 undefined 和 null 类型

+ +

下面的例子保存了一个空 Object 对象在 o:

+ +
let o = new Object()
+
+ +
let o = new Object(undefined)
+
+ +
let o = new Object(null)
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-object-constructor', 'Object constructor')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Object.Object")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/observe/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/observe/index.html new file mode 100644 index 0000000000..e37cc6ab6f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/observe/index.html @@ -0,0 +1,160 @@ +--- +title: Object.observe() +slug: Web/JavaScript/Reference/Global_Objects/Object/observe +tags: + - ECMAScript7 + - Experimental + - JavaScript + - Method + - Object + - observe +translation_of: Archive/Web/JavaScript/Object.observe +--- +
{{JSRef}} {{obsolete_header}}
+ +

概述

+ +

Object.observe() 方法用于异步地监视一个对象的修改。当对象属性被修改时,方法的回调函数会提供一个有序的修改流。然而,这个接口已经被废弃并从各浏览器中移除。你可以使用更通用的 {{jsxref("Proxy")}} 对象替代。

+ +

语法

+ +
Object.observe(obj, callback[, acceptList])
+ +

参数

+ +
+
obj
+
被监控的对象.
+
callback
+
当对象被修改时触发的回调函数,其参数为: +
+
changes
+
一个数组,其中包含的每一个对象代表一个修改行为。每个修改行为的对象包含: +
    +
  • name: 被修改的属性名称
  • +
  • object: 修改后该对象的值
  • +
  • type: 表示对该对象做了何种类型的修改,可能的值为"add", "update", or "delete"
  • +
  • oldValue: 对象修改前的值。该值只在"update""delete"有效。
  • +
  •  
  • +
+
+
acceptList
+
在给定对象上给定回调中要监视的变化类型列表。如果省略, ["add", "update", "delete", "reconfigure", "setPrototype", "preventExtensions"] 将会被使用。
+
+
+
+ +

描述

+ +

callback 函数会在对象被改变时被调用,其参数为一个包含所有修改信息的有序的数组对象。

+ +

例子

+ +

例子: 打印出三种不同操作类型的日志

+ +
var obj = {
+  foo: 0,
+  bar: 1
+};
+
+Object.observe(obj, function(changes) {
+  console.log(changes);
+});
+
+obj.baz = 2;
+// [{name: 'baz', object: <obj>, type: 'add'}]
+
+obj.foo = 'hello';
+// [{name: 'foo', object: <obj>, type: 'update', oldValue: 0}]
+
+delete obj.baz;
+// [{name: 'baz', object: <obj>, type: 'delete', oldValue: 2}]
+
+ +

例子: 数据绑定

+ +
// 一个数据模型
+var user = {
+  id: 0,
+  name: 'Brendan Eich',
+  title: 'Mr.'
+};
+
+// 创建用户的greeting
+function updateGreeting() {
+  user.greeting = 'Hello, ' + user.title + ' ' + user.name + '!';
+}
+updateGreeting();
+
+Object.observe(user, function(changes) {
+  changes.forEach(function(change) {
+    // 当name或title属性改变时, 更新greeting
+    if (change.name === 'name' || change.name === 'title') {
+      updateGreeting();
+    }
+  });
+});
+
+ +

规范

+ +

Strawman proposal for ECMAScript 7.

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("36")}}{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("36")}}{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/parent/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/parent/index.html new file mode 100644 index 0000000000..8597b6c4a3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/parent/index.html @@ -0,0 +1,43 @@ +--- +title: Object.prototype.__parent__ +slug: Web/JavaScript/Reference/Global_Objects/Object/Parent +tags: + - JavaScript + - 原型 + - 对象 + - 属性 + - 已废弃 + - 非标准 +translation_of: Archive/Web/JavaScript/Object.parent +--- +
{{JSRef}}{{Non-standard_Header}}{{Obsolete_Header("gecko2")}}
+ +

The __parent__ property used to point to an object's context, but it has been removed.

+ +

指向一个对象的上下文.

+ +

语法

+ +
obj.__parent__
+ +

描述

+ +

对于最顶层对象来说,这个属性的值就是全局对象 window。

+ +

规范

+ +

不属于任何规范。

+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Object.parent")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/preventextensions/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/preventextensions/index.html new file mode 100644 index 0000000000..81c8a451a2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/preventextensions/index.html @@ -0,0 +1,131 @@ +--- +title: Object.preventExtensions() +slug: Web/JavaScript/Reference/Global_Objects/Object/preventExtensions +tags: + - ECMAScript 5 + - JavaScript + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/preventExtensions +--- +
{{JSRef("Global_Objects", "Object")}}
+ +

Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。

+ +

{{EmbedInteractiveExample("pages/js/object-preventextensions.html")}}

+ +

语法

+ +
Object.preventExtensions(obj)
+ +

参数

+ +
+
obj
+
将要变得不可扩展的对象。
+
+

返回值

+
+
已经不可扩展的对象。
+
+ +

描述

+ +

如果一个对象可以添加新的属性,则这个对象是可扩展的。Object.preventExtensions()将对象标记为不再可扩展,这样它将永远不会具有它被标记为不可扩展时持有的属性之外的属性。注意,一般来说,不可扩展对象的属性可能仍然可被删除。尝试将新属性添加到不可扩展对象将静默失败或抛出{{jsxref("TypeError")}}(最常见的情况是{{jsxref("Functions_and_function_scope/Strict_mode", "strict mode", "", 1)}}中,但不排除其他情况)。

+ +

Object.preventExtensions()仅阻止添加自身的属性。但其对象类型的原型依然可以添加新的属性。

+ +

该方法使得目标对象的 [[prototype]]  不可变;任何重新赋值 [[prototype]] 操作都会抛出 TypeError 。这种行为只针对内部的 [[prototype]] 属性, 目标对象的其它属性将保持可变。

+ +

一旦将对象变为不可扩展的对象,就再也不能使其可扩展。

+ +

例子

+ +
// Object.preventExtensions将原对象变的不可扩展,并且返回原对象.
+var obj = {};
+var obj2 = Object.preventExtensions(obj);
+obj === obj2;  // true
+
+// 字面量方式定义的对象默认是可扩展的.
+var empty = {};
+Object.isExtensible(empty) //=== true
+
+// ...但可以改变.
+Object.preventExtensions(empty);
+Object.isExtensible(empty) //=== false
+
+// 使用Object.defineProperty方法为一个不可扩展的对象添加新属性会抛出异常.
+var nonExtensible = { removable: true };
+Object.preventExtensions(nonExtensible);
+Object.defineProperty(nonExtensible, "new", { value: 8675309 }); // 抛出TypeError异常
+
+// 在严格模式中,为一个不可扩展对象的新属性赋值会抛出TypeError异常.
+function fail()
+{
+  "use strict";
+  nonExtensible.newProperty = "FAIL"; // throws a TypeError
+}
+fail();
+
+ +

​​​​

+ +

不可扩展对象的原型是不可变的:

+ +
var fixed = Object.preventExtensions({});
+// throws a 'TypeError'.
+fixed.__proto__ = { oh: 'hai' };
+ +

Notes

+ +

在 ES5 中,如果参数不是一个对象类型(而是原始类型),将抛出一个{{jsxref("TypeError")}}异常。在 ES2015 中,非对象参数将被视为一个不可扩展的普通对象,因此会被直接返回。

+ +
Object.preventExtensions(1);
+// TypeError: 1 is not an object (ES5 code)
+
+Object.preventExtensions(1);
+// 1                             (ES2015 code)
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.10', 'Object.preventExtensions')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.8.5.
{{SpecName('ES6', '#sec-object.preventextensions', 'Object.preventExtensions')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.preventextensions', 'Object.preventExtensions')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.preventExtensions")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/propertyisenumerable/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/propertyisenumerable/index.html new file mode 100644 index 0000000000..b74e6bc26b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/propertyisenumerable/index.html @@ -0,0 +1,146 @@ +--- +title: Object.prototype.propertyIsEnumerable() +slug: Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable +tags: + - JavaScript + - Method + - Object + - Prototype + - 对象 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable +--- +
{{JSRef}}
+ +

propertyIsEnumerable() 方法返回一个布尔值,表示指定的属性是否可枚举。

+ +
{{EmbedInteractiveExample("pages/js/object-prototype-propertyisenumerable.html")}}
+ + + +

语法

+ +
obj.propertyIsEnumerable(prop)
+ +

参数

+ +
+
prop
+
需要测试的属性名。
+
+ +

返回值

+ +

用来表示指定的属性名是否可枚举的{{jsxref("Boolean", "布尔值")}}。

+ +

描述

+ +

每个对象都有一个 propertyIsEnumerable 方法。此方法可以确定对象中指定的属性是否可以被 {{jsxref("Statements/for...in", "for...in")}} 循环枚举,但是通过原型链继承的属性除外。如果对象没有指定的属性,则此方法返回 false

+ +

例子

+ +

propertyIsEnumerable 方法的基本用法

+ +

下面的例子演示了 propertyIsEnumerable 方法在普通对象和数组上的基本用法:

+ +
var o = {};
+var a = [];
+o.prop = 'is enumerable';
+a[0] = 'is enumerable';
+
+o.propertyIsEnumerable('prop'); // 返回 true
+a.propertyIsEnumerable(0);      // 返回 true
+ +

用户自定义对象和内置对象

+ +

下面的例子演示了用户自定义对象和内置对象上属性可枚举性的区别.

+ +
var a = ['is enumerable'];
+
+a.propertyIsEnumerable(0);        // 返回 true
+a.propertyIsEnumerable('length'); // 返回 false
+
+Math.propertyIsEnumerable('random'); // 返回 false
+this.propertyIsEnumerable('Math');   // 返回 false
+ +

自身属性和继承属性

+ +
var a = [];
+a.propertyIsEnumerable('constructor'); // 返回 false
+
+function firstConstructor() {
+  this.property = 'is not enumerable';
+}
+
+firstConstructor.prototype.firstMethod = function() {};
+
+function secondConstructor() {
+  this.method = function method() { return 'is enumerable'; };
+}
+
+secondConstructor.prototype = new firstConstructor;
+secondConstructor.prototype.constructor = secondConstructor;
+
+var o = new secondConstructor();
+o.arbitraryProperty = 'is enumerable';
+
+o.propertyIsEnumerable('arbitraryProperty'); // 返回 true
+o.propertyIsEnumerable('method');            // 返回 true
+o.propertyIsEnumerable('property');          // 返回 false
+
+o.property = 'is enumerable';
+
+o.propertyIsEnumerable('property');          // 返回 true
+
+// 之所以这些会返回 false,是因为,在原型链上 propertyIsEnumerable 不被考虑
+// (尽管最后两个在 for-in 循环中可以被循环出来)。
+o.propertyIsEnumerable('prototype');   // 返回 false (根据 JS 1.8.1/FF3.6)
+o.propertyIsEnumerable('constructor'); // 返回 false
+o.propertyIsEnumerable('firstMethod'); // 返回 false
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition
{{SpecName('ES5.1', '#sec-15.2.4.7', 'Object.prototype.propertyIsEnumerable')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-object.prototype.propertyisenumerable', 'Object.prototype.propertyIsEnumerable')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.prototype.propertyisenumerable', 'Object.prototype.propertyIsEnumerable')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Object.propertyIsEnumerable")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/proto/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/proto/index.html new file mode 100644 index 0000000000..7a9d4dfefd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/proto/index.html @@ -0,0 +1,142 @@ +--- +title: Object.prototype.__proto__ +slug: Web/JavaScript/Reference/Global_Objects/Object/proto +tags: + - ECMAScript 2015 + - JavaScript + - Object + - Property + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Object/proto +--- +
{{JSRef}}{{Deprecated_header}}
+ +
+

警告: 通过现代浏览器的操作属性的便利性,可以改变一个对象的 [[Prototype]] 属性, 这种行为在每一个JavaScript引擎和浏览器中都是一个非常慢且影响性能的操作,使用这种方式来改变和继承属性是对性能影响非常严重的,并且性能消耗的时间也不是简单的花费在 obj.__proto__ = ... 语句上, 它还会影响到所有继承来自该 [[Prototype]] 的对象,如果你关心性能,你就不应该在一个对象中修改它的 [[Prototype]]。相反, 创建一个新的且可以继承 [[Prototype]] 的对象,推荐使用 {{jsxref("Object.create()")}}。

+
+ +
+

警告:Object.prototype.__proto__ 已被大多数浏览器厂商所支持的今天,其存在和确切行为仅在ECMAScript 2015规范中被标准化为传统功能,以确保Web浏览器的兼容性。为了更好的支持,建议只使用 {{jsxref("Object.getPrototypeOf()")}}。

+
+ +
{{jsxref("Object.prototype")}} 的 __proto__  属性是一个访问器属性(一个getter函数和一个setter函数), 暴露了通过它访问的对象的内部[[Prototype]] (一个对象或 {{jsxref("Global_Objects/null", "null")}})。
+ +
+ +

使用__proto__是有争议的,也不鼓励使用它。因为它从来没有被包括在EcmaScript语言规范中,但是现代浏览器都实现了它。__proto__属性已在ECMAScript 6语言规范中标准化,用于确保Web浏览器的兼容性,因此它未来将被支持。它已被不推荐使用, 现在更推荐使用{{jsxref("Object.getPrototypeOf")}}/{{jsxref("Reflect.getPrototypeOf")}} 和{{jsxref("Object.setPrototypeOf")}}/{{jsxref("Reflect.setPrototypeOf")}}(尽管如此,设置对象的[[Prototype]]是一个缓慢的操作,如果性能是一个问题,应该避免)。

+ +

__proto__ 属性也可以在对象文字定义中使用对象[[Prototype]]来创建,作为{{jsxref("Object.create()")}} 的一个替代。 请参阅: object initializer / literal syntax.

+ +

语法

+ +
let Circle = function () {};
+let shape = {};
+let circle = new Circle();
+
+// 设置该对象的原型链引用
+// 过时且不推荐使用的。这里只是举个例子,尽量不要在生产环境中这样做。
+shape.__proto__ = circle;
+
+// 判断该对象的原型链引用是否属于circle
+console.log(shape.__proto__ === circle); // true
+
+ +
let shape = function () {};
+let p = {
+    a: function () {
+        console.log('aaa');
+    }
+};
+shape.prototype.__proto__ = p;
+
+let circle = new shape();
+circle.a();//aaa
+console.log(shape.prototype === circle.__proto__);//true
+
+//或者
+let shape = function () {};
+var p = {
+    a: function () {
+        console.log('a');
+    }
+};
+
+let circle = new shape();
+circle.__proto__ = p;
+circle.a(); //  a
+console.log(shape.prototype === circle.__proto__);//false
+
+//或者
+function test() {}
+test.prototype.myname = function () {
+    console.log('myname');
+}
+let a = new test()
+console.log(a.__proto__ === test.prototype);//true
+a.myname();//myname
+
+//或者
+let fn = function () {};
+fn.prototype.myname = function () {
+    console.log('myname');
+}
+
+let obj = {
+    __proto__: fn.prototype
+};
+
+obj.myname();//myname
+
+ +

注意:这是两个下划线,后面是五个字符的 “proto” ,后面再跟两个下划线。

+ +

描述

+ +

__proto__的读取器(getter)暴露了一个对象的内部 [[Prototype]] 。对于使用对象字面量创建的对象,这个值是 {{jsxref("Object.prototype")}}。对于使用数组字面量创建的对象,这个值是 {{jsxref("Array.prototype")}}。对于functions,这个值是{{jsxref("Function.prototype")}}。对于使用 new fun 创建的对象,其中fun是由js提供的内建构造器函数之一({{jsxref("Array")}}, {{jsxref("Boolean")}}, {{jsxref("Date")}}, {{jsxref("Number")}}, {{jsxref("Object")}}, {{jsxref("String")}} 等等),这个值总是fun.prototype。对于用js定义的其他js构造器函数创建的对象,这个值就是该构造器函数的prototype属性。

+ +

__proto__ 的设置器(setter)允许对象的 [[Prototype]]被变更。前提是这个对象必须通过 {{jsxref("Object.isExtensible()")}} 判断为是可扩展的,如果不可扩展,则会抛出一个 {{jsxref("Global_Objects/TypeError", "TypeError")}} 错误。要变更的值必须是一个object或{{jsxref("Global_Objects/null", "null")}},提供其它值将不起任何作用。

+ +

要理解原型如何被使用,请查看相关文章:Inheritance and the prototype chain

+ +

.__proto__属性是{{jsxref("Object.prototype")}} 一个简单的访问器属性,其中包含了get(获取)和set(设置)的方法,任何一个__proto__的存取属性都继承于{{jsxref("Object.prototype")}},但一个访问属性如果不是来源于{{jsxref("Object.prototype")}}就不拥有.__proto__属性,譬如一个元素设置了其他的.__proto__属性在{{jsxref("Object.prototype")}}之前,将会覆盖原有的{{jsxref("Object.prototype")}}。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-additional-properties-of-the-object.prototype-object', 'Object.prototype.__proto__')}}{{Spec2('ES6')}}Included in the (normative) annex for additional ECMAScript legacy features for Web browsers (note that the specification codifies what is already in implementations).
{{SpecName('ESDraft', '#sec-additional-properties-of-the-object.prototype-object', 'Object.prototype.__proto__')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容情况

+ + + +

{{Compat("javascript.builtins.Object.proto")}}

+ +

兼容性注意事项

+ +

在 ECMAScript 2015(ES6)的规范要求中,支持__proto__ 是各大Web浏览器厂商的要求(虽然符合规范),但其他环境下因为历史遗留的问题,也有可能被使用和支持。 

+ +

更多请参考

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/prototype/index.html new file mode 100644 index 0000000000..c3a7d022f7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/prototype/index.html @@ -0,0 +1,194 @@ +--- +title: Object.prototype +slug: Web/JavaScript/Reference/Global_Objects/Object/prototype +tags: + - JavaScript + - Object + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Object +--- +
{{JSRef}}
+ +

Object.prototype 属性表示 {{jsxref("Object")}} 的原型对象。

+ +

{{js_property_attributes(0, 0, 0)}}

+ +

描述

+ +

几乎所有的 JavaScript 对象都是 {{jsxref("Object")}} 的实例;一个典型的对象继承了Object.prototype的属性(包括方法),尽管这些属性可能被遮蔽(亦称为覆盖)。但是有时候可能故意创建不具有典型原型链继承的对象,比如通过{{jsxref("Object.create", "Object.create(null)")}}创建的对象,或者通过{{jsxref("Object.setPrototypeOf")}}方法改变原型链。

+ +

改变Object原型,会通过原型链改变所有对象;除非在原型链中进一步覆盖受这些变化影响的属性和方法。这提供了一个非常强大的、但有潜在危险的机制来覆盖或扩展对象行为。

+ +

属性

+ +
+
{{jsxref("Object.prototype.constructor")}}
+
特定的函数,用于创建一个对象的原型。
+
{{jsxref("Object.prototype.__proto__")}} {{non-standard_inline}}
+
指向当对象被实例化的时候,用作原型的对象。
+
{{jsxref("Object.prototype.__noSuchMethod__")}} {{non-standard_inline}}
+
当未定义的对象成员被调用作方法的时候,允许定义并执行的函数。
+
{{jsxref("Object.prototype.__count__")}} {{obsolete_inline}}
+
用于直接返回用户定义的对象中可数的属性的数量。已被废除。
+
{{jsxref("Object.prototype.__parent__")}} {{obsolete_inline}}
+
用于指向对象的内容。已被废除。
+
+ +

方法

+ +
+
{{jsxref("Object.prototype.__defineGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
关联一个函数到一个属性。访问该函数时,执行该函数并返回其返回值。
+
{{jsxref("Object.prototype.__defineSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
关联一个函数到一个属性。设置该函数时,执行该修改属性的函数。
+
{{jsxref("Object.prototype.__lookupGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
返回使用 {{jsxref("Object.defineGetter", "__defineGetter__")}} 定义的方法函数 。
+
{{jsxref("Object.prototype.__lookupSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
返回使用 {{jsxref("Object.defineSetter", "__defineSetter__")}} 定义的方法函数。
+
{{jsxref("Object.prototype.hasOwnProperty()")}}
+
返回一个布尔值 ,表示某个对象是否含有指定的属性,而且此属性非原型链继承的。
+
{{jsxref("Object.prototype.isPrototypeOf()")}}
+
返回一个布尔值,表示指定的对象是否在本对象的原型链中。
+
{{jsxref("Object.prototype.propertyIsEnumerable()")}}
+
判断指定属性是否可枚举,内部属性设置参见 ECMAScript [[Enumerable]] attribute
+
{{jsxref("Object.prototype.toSource()")}} {{non-standard_inline}}
+
返回字符串表示此对象的源代码形式,可以使用此字符串生成一个新的相同的对象。
+
{{jsxref("Object.prototype.toLocaleString()")}}
+
直接调用 {{jsxref("Object.toString", "toString()")}}方法。
+
{{jsxref("Object.prototype.toString()")}}
+
返回对象的字符串表示。
+
{{jsxref("Object.prototype.unwatch()")}} {{non-standard_inline}}
+
移除对象某个属性的监听。
+
{{jsxref("Object.prototype.valueOf()")}}
+
返回指定对象的原始值。
+
{{jsxref("Object.prototype.watch()")}} {{non-standard_inline}}
+
给对象的某个属性增加监听。
+
{{jsxref("Object.prototype.eval()")}} {{obsolete_inline}}
+
在指定对象为上下文情况下执行javascript字符串代码,已经废弃。
+
+ +

示例

+ +

当改变现有的 Object.prototype method(方法)的行为时,考虑在现有逻辑之前或之后通过封装你的扩展来注入代码。例如,此(未测试的)代码将在内置逻辑或其他人的扩展执行之前 pre-conditionally(预条件地)执行自定义逻辑。

+ +

当一个函数被调用时,调用的参数被保留在类似数组 "变量" 的参数中。例如, 在调用 "myFn (a、b、c)"时, 在myFn 的主体内的参数将包含 3个类似数组的元素对应于 (a、b、c)。 使用钩子修改原型时,只需通过调用该函数的 apply (),将 this 与参数 (调用状态) 传递给当前行为。这种模式可以用于任何原型,如 Node.prototype、 Function.prototype 等.

+ +
var current = Object.prototype.valueOf;
+
+// 由于我的属性 "-prop-value"是交叉性的, 并不总是
+// 在同一个原型链上,我想要修改 Object.prototype:
+Object.prototype.valueOf = function() {
+  if (this.hasOwnProperty('-prop-value')) {
+    return this['-prop-value'];
+  } else {
+    // 它看起来不像我的对象之一,因此,让我们退回到
+    // 默认行为,通过尽可能地复制当前行为来实现.
+    // 此apply的行为类似于其他语言中的"super".
+    // 即使 valueOf() 不带参数, 其他的钩子可能会带有.
+    return current.apply(this, arguments);
+  }
+}
+ +

由于 JavaScript 并不完全具有子类对象, 所以原型是一种有用的变通方法, 可以使用某些函数的 "基类" 对象来充当对象。例如:

+ +
var Person = function(name) {
+  this.name = name;
+  this.canTalk = true;
+};
+
+Person.prototype.greet = function() {
+  if (this.canTalk) {
+    console.log('Hi, I am ' + this.name);
+  }
+};
+
+var Employee = function(name, title) {
+  Person.call(this, name);
+  this.title = title;
+};
+
+Employee.prototype = Object.create(Person.prototype);
+
+Employee.prototype.greet = function() {
+  if (this.canTalk) {
+    console.log('Hi, I am ' + this.name + ', the ' + this.title);
+  }
+};
+
+var Customer = function(name) {
+  Person.call(this, name);
+};
+
+Customer.prototype = Object.create(Person.prototype);
+
+var Mime = function(name) {
+  Person.call(this, name);
+  this.canTalk = false;
+};
+
+Mime.prototype = Object.create(Person.prototype);
+
+var bob = new Employee('Bob', 'Builder');
+var joe = new Customer('Joe');
+var rg = new Employee('Red Green', 'Handyman');
+var mike = new Customer('Mike');
+var mime = new Mime('Mime');
+
+bob.greet();
+// Hi, I am Bob, the Builder
+
+joe.greet();
+// Hi, I am Joe
+
+rg.greet();
+// Hi, I am Red Green, the Handyman
+
+mike.greet();
+// Hi, I am Mike
+
+mime.greet();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.2.3.1', 'Object.prototype')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-object.prototype', 'Object.prototype')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.prototype', 'Object.prototype')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.prototype")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/seal/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/seal/index.html new file mode 100644 index 0000000000..7a18ee2e91 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/seal/index.html @@ -0,0 +1,151 @@ +--- +title: Object.seal() +slug: Web/JavaScript/Reference/Global_Objects/Object/seal +tags: + - ECMAScript 5 + - JavaScript + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/seal +--- +
{{JSRef}}
+ +
Object.seal()方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。
+ +
+ +
{{EmbedInteractiveExample("pages/js/object-prototype-seal.html")}}
+ + + +

语法

+ +
Object.seal(obj)
+ +

参数

+ +
+
obj
+
将要被密封的对象。
+
+ +

返回值

+ +

被密封的对象。

+ +

描述

+ +

通常,一个对象是{{jsxref("Object.isExtensible()", "可扩展的", "", 1)}}(可以添加新的属性)。密封一个对象会让这个对象变的不能添加新属性,且所有已有属性会变的不可配置。属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出{{jsxref("TypeError")}}(在{{jsxref("Strict_mode", "严格模式", "", 1)}} 中最常见的,但不唯一)。

+ +

不会影响从原型链上继承的属性。但 {{jsxref("Object.proto", "__proto__")}} ( {{deprecated_inline}} ) 属性的值也会不能修改。

+ +

返回被密封对象的引用。

+ +

例子

+ +
var obj = {
+  prop: function() {},
+  foo: 'bar'
+};
+
+// 可以添加新的属性
+// 可以更改或删除现有的属性
+obj.foo = 'baz';
+obj.lumpy = 'woof';
+delete obj.prop;
+
+var o = Object.seal(obj);
+
+o === obj; // true
+Object.isSealed(obj); // === true
+
+// 仍然可以修改密封对象的属性值
+obj.foo = 'quux';
+
+
+// 但是你不能将属性重新定义成为访问器属性
+// 反之亦然
+Object.defineProperty(obj, 'foo', {
+  get: function() { return 'g'; }
+}); // throws a TypeError
+
+// 除了属性值以外的任何变化,都会失败.
+obj.quaxxor = 'the friendly duck';
+// 添加属性将会失败
+delete obj.foo;
+// 删除属性将会失败
+
+// 在严格模式下,这样的尝试将会抛出错误
+function fail() {
+  'use strict';
+  delete obj.foo; // throws a TypeError
+  obj.sparky = 'arf'; // throws a TypeError
+}
+fail();
+
+// 通过Object.defineProperty添加属性将会报错
+Object.defineProperty(obj, 'ohai', {
+  value: 17
+}); // throws a TypeError
+Object.defineProperty(obj, 'foo', {
+  value: 'eit'
+}); // 通过Object.defineProperty修改属性值
+ +

注意

+ +

在ES5中,如果这个方法的参数不是一个(原始)对象,那么它将导致{{jsxref("TypeError")}}。在ES2015中,非对象参数将被视为已被密封的普通对象,会直接返回它。

+ +
Object.seal(1);
+// TypeError: 1 is not an object (ES5 code)
+
+Object.seal(1);
+// 1                             (ES2015 code)
+ +

对比 Object.freeze()

+ +

使用Object.freeze()冻结的对象中的现有属性值是不可变的。用Object.seal()密封的对象可以改变其现有属性值。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.2.3.8', 'Object.seal')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.8.5.
{{SpecName('ES6', '#sec-object.seal', 'Object.seal')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.seal', 'Object.seal')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.builtins.Object.seal")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/setprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/setprototypeof/index.html new file mode 100644 index 0000000000..20d34f2b92 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/setprototypeof/index.html @@ -0,0 +1,233 @@ +--- +title: Object.setPrototypeOf() +slug: Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf +tags: + - Array + - Class + - ECMAScript6 + - ES6 + - JavaScript + - Object.setPrototypeOf() + - Typescript + - setPrototypeOf() + - 对象 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf +--- +
{{JSRef}}
+ +
Object.setPrototypeOf() 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或  {{jsxref("null")}}。
+ +
+ +
+

警告: 由于现代 JavaScript 引擎优化属性访问所带来的特性的关系,更改对象的 [[Prototype]]各个浏览器和 JavaScript 引擎上都是一个很慢的操作。其在更改继承的性能上的影响是微妙而又广泛的,这不仅仅限于 obj.__proto__ = ... 语句上的时间花费,而且可能会延伸到任何代码,那些可以访问任何[[Prototype]]已被更改的对象的代码。如果你关心性能,你应该避免设置一个对象的 [[Prototype]]。相反,你应该使用 {{jsxref("Object.create()")}}来创建带有你想要的[[Prototype]]的新对象。

+
+ +

语法

+ +
Object.setPrototypeOf(obj, prototype)
+ +

参数

+ +
+
obj
+
要设置其原型的对象。.
+
prototype
+
该对象的新原型(一个对象 或 {{jsxref("null")}}).
+
+ +

描述

+ +

如果对象的[[Prototype]]被修改成不可扩展(通过 {{jsxref("Object.isExtensible()")}}查看),就会抛出 {{jsxref("TypeError")}}异常。如果prototype参数不是一个对象或者{{jsxref("null")}}(例如,数字,字符串,boolean,或者 {{jsxref("undefined")}}),则什么都不做。否则,该方法将obj[[Prototype]]修改为新的值。

+ +

Object.setPrototypeOf()是ECMAScript 6最新草案中的方法,相对于 {{jsxref("Object.prototype.__proto__")}} ,它被认为是修改对象原型更合适的方法

+ +

示例

+ +
var dict = Object.setPrototypeOf({}, null);
+ +

Polyfill

+ +

我们必须借助非标准的  

+ +

使用较旧的 {{jsxref("Object.prototype.__proto__")}} 属性,我们可以很容易地定义Object.setPrototypeOf 如果它不可用:

+ +
if (!Object.setPrototypeOf) {
+    // 仅适用于Chrome和FireFox,在IE中不工作:
+     Object.prototype.setPrototypeOf = function(obj, proto) {
+         if(obj.__proto__) {
+             obj.__proto__ = proto;
+             return obj;
+         } else {
+             // 如果你想返回 prototype of Object.create(null):
+             var Fn = function() {
+                 for (var key in obj) {
+                     Object.defineProperty(this, key, {
+                         value: obj[key],
+                     });
+                 }
+             };
+             Fn.prototype = proto;
+             return new Fn();
+         }
+     }
+}
+
+ + + +

附加原型链

+ +

通过  Object.getPrototypeOf() 和 {{jsxref("Object.proto", "Object.prototype.__proto__")}} 的组合允许将一个原型链完整的附加到一个新的原型对象上:

+ +
/**
+*** Object.appendChain(@object, @prototype)
+*
+* Appends the first non-native prototype of a chain to a new prototype.
+* Returns @object (if it was a primitive value it will transformed into an object).
+*
+*** Object.appendChain(@object [, "@arg_name_1", "@arg_name_2", "@arg_name_3", "..."], "@function_body")
+*** Object.appendChain(@object [, "@arg_name_1, @arg_name_2, @arg_name_3, ..."], "@function_body")
+*
+* Appends the first non-native prototype of a chain to the native Function.prototype object, then appends a
+* new Function(["@arg"(s)], "@function_body") to that chain.
+* Returns the function.
+*
+**/
+
+Object.appendChain = function(oChain, oProto) {
+  if (arguments.length < 2) {
+    throw new TypeError('Object.appendChain - Not enough arguments');
+  }
+  if (typeof oProto === 'number' || typeof oProto === 'boolean') {
+    throw new TypeError('second argument to Object.appendChain must be an object or a string');
+  }
+
+  var oNewProto = oProto,
+      oReturn,
+      o2nd,
+      oLast;
+
+  oReturn = o2nd = oLast = oChain instanceof this ? oChain : new oChain.constructor(oChain);
+
+  for (var o1st = this.getPrototypeOf(o2nd);
+    o1st !== Object.prototype && o1st !== Function.prototype;
+    o1st = this.getPrototypeOf(o2nd)
+  ) {
+    o2nd = o1st;
+  }
+
+  if (oProto.constructor === String) {
+    oNewProto = Function.prototype;
+    oReturn = Function.apply(null, Array.prototype.slice.call(arguments, 1));
+    this.setPrototypeOf(oReturn, oLast);
+  }
+
+  this.setPrototypeOf(o2nd, oNewProto);
+  return oReturn;
+}
+ +

使用

+ +

例子一:向一个原型附加一个链

+ +
function Mammal() {
+  this.isMammal = 'yes';
+}
+
+function MammalSpecies(sMammalSpecies) {
+  this.species = sMammalSpecies;
+}
+
+MammalSpecies.prototype = new Mammal();
+MammalSpecies.prototype.constructor = MammalSpecies;
+
+var oCat = new MammalSpecies('Felis');
+
+console.log(oCat.isMammal);
+// 'yes'
+
+function Animal() {
+  this.breathing = 'yes';
+}
+
+Object.appendChain(oCat, new Animal());
+
+console.log(oCat.breathing);
+// 'yes'
+ +

例子二:将一个基本类型转化为对应的对象类型并添加到原型链上

+ +
function Symbol() {
+  this.isSymbol = 'yes';
+}
+
+var nPrime = 17;
+
+console.log(typeof nPrime); // 'number'
+
+var oPrime = Object.appendChain(nPrime, new Symbol());
+
+console.log(oPrime); // '17'
+console.log(oPrime.isSymbol); // 'yes'
+console.log(typeof oPrime); // 'object'
+ +

例子三:给函数类型的对象添加一个链,并添加一个新的方法到那个链上

+ +
function Person(sName) {
+  this.identity = sName;
+}
+
+var george = Object.appendChain(new Person('George'), 'console.log("Hello guys!!");');
+
+console.log(george.identity); // 'George'
+george(); // 'Hello guys!!'
+ +

说明书

+ + + + + + + + + + + + + + + + +
说明状态备注
{{SpecName('ES6', '#sec-object.setprototypeof', 'Object.setProtoypeOf')}} + + + + + + +
{{Spec2('ES6')}}
+
Initial definition.
+ +

浏览器兼容性

+ + + + + +

{{Compat("javascript.builtins.Object.setPrototypeOf")}}

+ +
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/tolocalestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/tolocalestring/index.html new file mode 100644 index 0000000000..611bfc560f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/tolocalestring/index.html @@ -0,0 +1,80 @@ +--- +title: Object.prototype.toLocaleString() +slug: Web/JavaScript/Reference/Global_Objects/Object/toLocaleString +tags: + - JavaScript + - Method + - Object + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Object/toLocaleString +--- +
{{JSRef("Global_Objects", "Object")}}
+ +

toLocaleString() 方法返回一个该对象的字符串表示。此方法被用于派生对象为了特定语言环境的目的(locale-specific purposes)而重载使用。

+ +

语法

+ +
obj.toLocaleString();
+
+ +

返回值

+ +

表示对象的字符串。

+ +

描述

+ +

{{jsxref("Object")}} toLocaleString 返回调用 {{jsxref("Object.toString", "toString()")}} 的结果。

+ +

该函数提供给对象一个通用的toLocaleString 方法,即使不是全部都可以使用它。 见下面的列表。

+ +

覆盖 toLocaleString 的对象

+ + + +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.2.4.3', 'Object.prototype.toLocaleString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-object.prototype.tolocalestring', 'Object.prototype.toLocaleString')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-object.prototype.tolocalestring', 'Object.prototype.toLocaleString')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Object.toLocaleString")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/tosource/index.html new file mode 100644 index 0000000000..a47cd4dbc2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/tosource/index.html @@ -0,0 +1,128 @@ +--- +title: Object.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/Object/toSource +tags: + - JavaScript + - Method + - Object + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Object/toSource +--- +
+
{{JSRef}} {{non-standard_header}}
+
+ +

toSource()方法返回一个表示对象源代码的字符串。

+ +

语法

+ +
Object.toSource(); obj.toSource()
+ +

返回值

+ +

一个表示对象的源代码的字符串。

+ +

描述

+ +

toSource()方法返回以下值:

+ + + +
function Object() {
+   [native code]
+}
+ + + +

在调试时,你可以通过toSource()来查看一个对象的内容。

+ +

重写toSource()方法

+ +

允许对象重写toSource()方法。例如:

+ +
function Person(name) {
+    this.name = name;
+}
+
+Person.prototype.toSource = function Person_toSource() {
+    return "new Person(" + uneval(this.name) + ")";
+};
+
+alert(new Person("Joe").toSource()); // ---> new Person("Joe")
+ +

内置的toSource方法

+ +

每个JavaScript核心类型都有它自己的toSource()方法.这些对象是:

+ + + +

循环引用限制

+ +

对于包含对自身的引用的对象 (例如, 循环链表或可以遍历两种方式的树), toSource()不会重新创建自引用, 如火狐24。例如:

+ +
var obj1 = {};
+var obj2 = { a: obj1 };
+obj1.b = obj2;
+
+console.log('Cyclical: ' + (obj1.b.a == obj1));
+
+var objSource = obj1.toSource(); // returns "({b:{a:{}}})"
+
+obj1 = eval(objSource);
+
+console.log('Cyclical: ' + (obj1.b.a == obj1));
+ +

如果使用循环结构, 并且需要 toSource(), 则对象必须提供对 toSource() 的重写,  无论是对构造函数的引用还是提供匿名函数。

+ +

示例

+ +

使用toSource()

+ +

下面的代码定义了一个Dog对象类型还创建了一个Dog类型的对象实例theDog

+ +
function Dog(name, breed, color, sex) {
+   this.name = name;
+   this.breed = breed;
+   this.color = color;
+   this.sex = sex;
+}
+
+theDog = new Dog("Gabby", "Lab", "chocolate", "girl");
+ +

theDog上调用toSource方法会显示出能定义该对象的源码:

+ +
theDog.toSource();
+// returns ({name:"Gabby", breed:"Lab", color:"chocolate", sex:"female"})
+ +

特性

+ +

不属于任何标准的一部分。在JavaScript1.3中实现。

+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.toSource")}}

+ +

相关链接

+ + + +

diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/tostring/index.html new file mode 100644 index 0000000000..a38a5d8913 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/tostring/index.html @@ -0,0 +1,139 @@ +--- +title: Object.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/Object/toString +tags: + - JavaScript + - Method + - Object + - Prototype + - 原型 + - 对象 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Object/toString +--- +

{{JSRef}}

+ +

toString() 方法返回一个表示该对象的字符串。

+ +
{{EmbedInteractiveExample("pages/js/object-prototype-tostring.html")}}
+ + + +

语法

+ +
obj.toString()
+ +

返回值

+ +

一个表示该对象的字符串。

+ +

描述

+ +

每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。以下代码说明了这一点:

+ +
var o = new Object();
+o.toString(); // returns [object Object]
+
+ +
注意:如的ECMAScript 5 和随后的 Errata 中所定义,从 JavaScript 1.8.5 开始,toString() 调用 {{jsxref("null")}} 返回[object Null],{{jsxref("undefined")}} 返回 [object Undefined]。请参阅下面的{{anch("Using_toString()_to_detect_object_class", "使用 toString() 检测对象类型")}}。
+ +

示例

+ +

覆盖默认的 toString 方法

+ +

可以自定义一个方法,来取代默认的 toString() 方法。该 toString() 方法不能传入参数,并且必须返回一个字符串。自定义的 toString() 方法可以是任何我们需要的值,但如果它附带有关对象的信息,它将变得非常有用。

+ +

以下代码定义了 Dog 对象类型,并创建了一个 Dog 类型的 theDog 对象:

+ +
function Dog(name,breed,color,sex) {
+  this.name = name;
+  this.breed = breed;
+  this.color = color;
+  this.sex = sex;
+}
+
+var theDog = new Dog("Gabby", "Lab", "chocolate", "female");
+ +

如果当前的对象调用了 toString() 方法,它将会返回从 {{jsxref("Object")}}继承而来的 toString() 方法的返回默认值:

+ +
theDog.toString(); // 返回 [object Object]
+ +

下面的代码中定义了一个叫做 dogToString() 的方法来覆盖默认的 toString() 方法。这个方法生成一个 "property = value;" 形式的字符串,该字符串包含了当前对象的 name、breed、color 和 sex 的值。

+ +
Dog.prototype.toString = function dogToString() {
+ var ret = "Dog " + this.name + " is a " + this.sex + " " + this.color + " " + this.breed;
+ return ret;
+}
+ +

也可以这样写

+ +
Dog.prototype.toString = function dogToString() {
+  return `Dog ${this.name} is a ${this.sex} ${this.color} ${this.breed}`;
+}
+
+ +

使用上述代码,任何时候在字符串上下文中使用 theDog.toString() 时,JavaScript 都会自动调用 dogToString() 方法(dogToString() 可以是一个匿名函数),并且返回以下字符串:

+ +
"Dog Gabby is a female chocolate Lab"
+ +

使用 toString() 检测对象类型

+ +

可以通过 toString() 来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg

+ +
var toString = Object.prototype.toString;
+
+toString.call(new Date); // [object Date]
+toString.call(new String); // [object String]
+toString.call(Math); // [object Math]
+
+//Since JavaScript 1.8.5
+toString.call(undefined); // [object Undefined]
+toString.call(null); // [object Null]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.2.4.2', 'Object.prototype.toString')}}{{Spec2('ES5.1')}}Call on {{jsxref("null")}} returns [object Null], and {{jsxref("undefined")}} returns [object Undefined]
{{SpecName('ES6', '#sec-object.prototype.tostring', 'Object.prototype.toString')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-object.prototype.tostring', 'Object.prototype.toString')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Object.toString")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/unobserve/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/unobserve/index.html new file mode 100644 index 0000000000..bcae6ae8e7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/unobserve/index.html @@ -0,0 +1,133 @@ +--- +title: Object.unobserve() +slug: Web/JavaScript/Reference/Global_Objects/Object/unobserve +translation_of: Archive/Web/JavaScript/Object.unobserve +--- +
{{JSRef}} {{non-standard_header}}
+ +

Object.unobserve() 是用来移除通过 {{jsxref("Object.observe()")}}设置的观察者的方法。

+ +

语法

+ +
Object.unobserve(obj, callback)
+ +

参数

+ +
+
obj
+
需要停止观察的对象。
+
callback
+
通过 observer 给 obj 对象设置的回调函数.
+
+ +

描述

+ +

Object.unobserve() 用来在 {{jsxref("Object.observe()")}} 被调用以后,从对象上移除一个观察者。

+ +

这个回调函数必须是一个函数的引用,而不能是一个匿名函数。因为这个引用将被用来移除之前设置的观察者方法。 给 Object.unobserve() 传入匿名函数作为回调是不起作用的, 它不能移除任何观察者方法。

+ +

例子

+ +

观察一个对象

+ +
var obj = {
+  foo: 0,
+  bar: 1
+};
+
+var observer = function(changes) {
+  console.log(changes);
+}
+
+Object.observe(obj, observer);
+​
+obj.newProperty = 2;
+// [{name: 'newProperty', object: <obj>, type: 'add'}]
+
+Object.unobserve(obj, observer);
+
+obj.foo = 1;
+// 回调函数不会被调用
+ +

使用匿名函数

+ +
var person = {
+  name : 'Ahmed',
+  age : 25
+};
+
+Object.observe(person, function (changes) {
+  console.log(changes);
+});
+
+person.age = 40;
+// [{name: 'age', object: <obj>, oldValue: 25, type: 'update'}]
+
+Object.unobserve(person, function (changes) {
+  console.log(changes);
+});
+
+person.age = 63;
+// [{name: 'age', object: <obj>, oldValue: 40, type: 'update'}]
+// 回调函数将会被调用
+
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("36")}}{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("36")}}{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/unwatch/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/unwatch/index.html new file mode 100644 index 0000000000..986154992d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/unwatch/index.html @@ -0,0 +1,105 @@ +--- +title: Object.prototype.unwatch() +slug: Web/JavaScript/Reference/Global_Objects/Object/unwatch +translation_of: Archive/Web/JavaScript/Object.unwatch +--- +
{{JSRef}}
+ +
+

警告 : 请尽量避免使用 unwatch() 和  {{jsxref("Object.prototype.watch", "watch()")}} . 这两个方法仅在 Gecko 中实现 , 并且他们过去主要作调试用. 另外, 使用 watchpoints 对性能有一系列的副面影响 ,特别是当使用全局对象,如 window. 你应该使用  setters and getters 或 proxies 来替代. 查阅 {{anch("Browser compatibility")}} 以获取更多信息.

+
+ +

unwatch() 删除一个 {{jsxref("Object.prototype.watch", "watch()")}} 设置的 watchpoint.

+ +

语法

+ +
obj.unwatch(prop)
+ +

参数

+ +
+
prop
+
想要停止监视的对象的属性名
+
+ +

描述

+ +

JavaScript调试器具有类似的功能,以及其他调试选项。有关调试器的信息  Venkman.

+ +

默认地, 这个方法 被每一个 {{jsxref("Object")}} 的子类继承 

+ +
+

Note: The reason for unwatch() to take the property name prop as its only parameter is due to the "single handler allowing" behavior of the {{jsxref("Object.watch", "watch()")}} method.

+
+ +

例子

+ +

See {{jsxref("Object.watch", "watch()")}}.

+ +

说明

+ +

Not part of any specifications. Implemented in JavaScript 1.2.

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

Compatibility notes

+ + + +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/valueof/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/valueof/index.html new file mode 100644 index 0000000000..4601b3c4c7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/valueof/index.html @@ -0,0 +1,208 @@ +--- +title: Object.prototype.valueOf() +slug: Web/JavaScript/Reference/Global_Objects/Object/valueOf +tags: + - JavaScript + - Method + - Object +translation_of: Web/JavaScript/Reference/Global_Objects/Object/valueOf +--- +
{{JSRef}}
+ +

valueOf() 方法返回指定对象的原始值。

+ +

语法

+ +
object.valueOf()
+ +

返回值

+ +

返回值为该对象的原始值。

+ +

描述

+ +

JavaScript调用valueOf方法将对象转换为原始值。你很少需要自己调用valueOf方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它。

+ +

默认情况下,valueOf方法由{{jsxref("Object")}}后面的每个对象继承。 每个内置的核心对象都会覆盖此方法以返回适当的值。如果对象没有原始值,则valueOf将返回对象本身。

+ +

JavaScript的许多内置对象都重写了该函数,以实现更适合自身的功能需要。因此,不同类型对象的valueOf()方法的返回值和返回值类型均可能不同。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
不同类型对象的valueOf()方法的返回值
对象返回值
Array返回数组对象本身。
Boolean布尔值。
Date存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。
Function函数本身。
Number数字值。
Object对象本身。这是默认情况。
String字符串值。
 Math 和 Error 对象没有 valueOf 方法。
+ +

你可以在自己的代码中使用valueOf将内置对象转换为原始值。 创建自定义对象时,可以覆盖Object.prototype.valueOf()来调用自定义方法,而不是默认{{jsxref("Object")}}方法。

+ +

覆盖自定义对象的 valueOf方法

+ +

你可以创建一个取代 valueOf方法的函数,你的方法必须不能传入参数。

+ +

假设你有个对象叫 MyNumberType而你想为它创建一个valueOf方法。下面的代码为valueOf方法赋予了一个自定义函数:

+ +
MyNumberType.prototype.valueOf = function() { return customPrimitiveValue; };
+ +
 
+ +

有了这样的一个方法,下一次每当MyNumberType要被转换为原始类型值时,JavaScript 在此之前会自动调用自定义的valueOf方法。

+ +

valueOf方法一般都会被 JavaScript 自动调用,但你也可以像下面代码那样自己调用:

+ +
myNumberType.valueOf()
+ +
+

注意:字符串上下文中的对象通过 {{jsxref("Object.toString", "toString()")}}方法转换,这与使用valueOf转换为原始字符串的{{jsxref("String")}}对象不同。所有对象都能转换成一个“[object 类型]”这种格式的字符串。但是很多对象不能转换为数字,布尔或函数。

+
+ +

示例

+ +

使用 valueOf

+ +
// Array:返回数组对象本身
+var array = ["ABC", true, 12, -5];
+console.log(array.valueOf() === array);   // true
+
+// Date:当前时间距1970年1月1日午夜的毫秒数
+var date = new Date(2013, 7, 18, 23, 11, 59, 230);
+console.log(date.valueOf());   // 1376838719230
+
+// Number:返回数字值
+var num =  15.26540;
+console.log(num.valueOf());   // 15.2654
+
+// 布尔:返回布尔值true或false
+var bool = true;
+console.log(bool.valueOf() === bool);   // true
+
+// new一个Boolean对象
+var newBool = new Boolean(true);
+// valueOf()返回的是true,两者的值相等
+console.log(newBool.valueOf() == newBool);   // true
+// 但是不全等,两者类型不相等,前者是boolean类型,后者是object类型
+console.log(newBool.valueOf() === newBool);   // false
+
+// Function:返回函数本身
+function foo(){}
+console.log( foo.valueOf() === foo );   // true
+var foo2 =  new Function("x", "y", "return x + y;");
+console.log( foo2.valueOf() );
+/*
+ƒ anonymous(x,y
+) {
+return x + y;
+}
+*/
+
+// Object:返回对象本身
+var obj = {name: "张三", age: 18};
+console.log( obj.valueOf() === obj );   // true
+
+// String:返回字符串值
+var str = "http://www.xyz.com";
+console.log( str.valueOf() === str );   // true
+
+// new一个字符串对象
+var str2 = new String("http://www.xyz.com");
+// 两者的值相等,但不全等,因为类型不同,前者为string类型,后者为object类型
+console.log( str2.valueOf() === str2 );   // false
+ +

 

+ +

改写 .prototype.valueof

+ +
function MyNumberType(n) {
+    this.number = n;
+}
+
+MyNumberType.prototype.valueOf = function() {
+    return this.number;
+};
+
+var myObj = new MyNumberType(4);
+myObj + 3; // 7
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.2.4.4', 'Object.prototype.valueOf')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-object.prototype.valueof', 'Object.prototype.valueOf')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-object.prototype.valueof', 'Object.prototype.valueOf')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.valueOf")}}

+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/values/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/values/index.html new file mode 100644 index 0000000000..42d9cced00 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/values/index.html @@ -0,0 +1,113 @@ +--- +title: Object.values() +slug: Web/JavaScript/Reference/Global_Objects/Object/values +tags: + - JavaScript + - Method + - Object + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Object/values +--- +
{{JSRef}}
+ +

Object.values()方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用{{jsxref("Statements/for...in", "for...in")}}循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。

+ +

语法

+ +
Object.values(obj)
+ +

参数

+ +
+
obj
+
被返回可枚举属性值的对象。
+
+ +

返回值

+ +

一个包含对象自身的所有可枚举属性值的数组。

+ +

描述

+ +

Object.values()返回一个数组,其元素是在对象上找到的可枚举属性值。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。

+ +

示例

+ +
var obj = { foo: 'bar', baz: 42 };
+console.log(Object.values(obj)); // ['bar', 42]
+
+// array like object
+var obj = { 0: 'a', 1: 'b', 2: 'c' };
+console.log(Object.values(obj)); // ['a', 'b', 'c']
+
+// array like object with random key ordering
+// when we use numeric keys, the value returned in a numerical order according to the keys
+var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
+console.log(Object.values(an_obj)); // ['b', 'c', 'a']
+
+// getFoo is property which isn't enumerable
+var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
+my_obj.foo = 'bar';
+console.log(Object.values(my_obj)); // ['bar']
+
+// non-object argument will be coerced to an object
+console.log(Object.values('foo')); // ['f', 'o', 'o']
+ +

 

+ +

Polyfill 

+ +

如果要 Object.values兼容不支持它的旧环境,可在 tc39/proposal-object-values-entries 或 es-shims/Object.values 中找到 Polyfill 。

+ +

根据Object.keys()的Polyfill仿写一个:

+ +
if (!Object.values) Object.values = function(obj) {
+    if (obj !== Object(obj))
+        throw new TypeError('Object.values called on a non-object');
+    var val=[],key;
+    for (key in obj) {
+        if (Object.prototype.hasOwnProperty.call(obj,key)) {
+            val.push(obj[key]);
+        }
+    }
+    return val;
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-object.values', 'Object.values')}}{{Spec2('ESDraft')}}Initial definition.
{{SpecName('ES8', '#sec-object.values', 'Object.values')}}{{Spec2('ES8')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.values")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/watch/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/watch/index.html new file mode 100644 index 0000000000..540967eee3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/object/watch/index.html @@ -0,0 +1,201 @@ +--- +title: Object.prototype.watch() +slug: Web/JavaScript/Reference/Global_Objects/Object/watch +tags: + - Debugging + - Deprecated + - JavaScript + - Method + - Object + - Obsolete + - Prototype +translation_of: Archive/Web/JavaScript/Object.watch +--- +

{{JSRef}}

+ +
+

警告: 通常来讲,你应该尽量避免使用 watch()和  {{jsxref("Object.prototype.unwatch", "unwatch()")}} 这两个方法。因为只有 Gecko 实现了这两个方法,并且它们主要是为了在调试方便。另外,使用 watchpoint 对性能有严重的负面影响,在全局对象(如 window)上使用时尤其如此。你可以使用 setters and getters 或者 proxy 代替。参见 {{ anch("Compatibility") }} 了解详情。

+
+ +

watch() 方法会监视属性是否被赋值并在赋值时运行相关函数。

+ +

语法

+ +
obj.watch(prop, handler)
+ +

参数

+ +
+
prop
+
想要监视值是否发生变化的指定对象的某个属性的属性名称
+
+ +
+
handler
+
当指定的属性发生变化时执行的回调函数
+
+ +

返回值

+ +

{{jsxref("undefined")}}.

+ +

描述

+ +

监视对指定对象的名为 prop 属性的赋值操作,只要 prop 属性被赋值,便调用 handler(prop, oldval, newval) 回调函数,并将函数返回值保存到该属性。 通过返回修改的新值(或者返回旧值),一个监视点可以过滤(或使之为 null )赋值。

+ +

如果你删除某个设置监视点的属性,该监视点并不会消失。如果你之后重新创建这个属性,监视点仍然有效。

+ +

要移除某个监视点,使用 unwatch() 方法。默认所有 Object 的后代都将继承 watch 方法。

+ +

JavaScript 调试器有与之相似的机制以及其它调试选项。需要更多有关调试器的信息,请查阅 Venkman

+ +

对于 Firefox,handler 只会被脚本内的赋值操作激活,并不包括本地代码。举个例子,如果用户点击一个指向当前文档内的某个锚点, window.watch('location', myHandler) 不会回调 myHandler ,但 window.location += '#myAnchor' 将触发回调  myHandler

+ +
注意: 对一个对象的指定属性调用 watch()  将覆盖先前关联的 handler。
+ +

例子

+ +

使用 watchunwatch

+ +
var o = {p:1};
+o.watch("p",
+  function (id, oldval, newval) {
+    console.log("o." + id + "由" + oldval + " 变为 " + newval);
+    return newval;
+  });
+
+o.p = 2;
+o.p = 3;
+delete o.p;
+o.p = 4;
+
+o.unwatch('p');
+o.p = 5;
+
+ +

上面的代码显示结果如下:

+ +
o.p 由 1 变为 2
+o.p 由 2 变为 3
+o.p 由 undefined 变为 4
+
+ +

使用 watch 来验证一个对象的属性

+ +

你可以使用 watch 来检测一个对象的属性赋值是否是合法的.下例演示了如何确保每个人始终具有一个合法的名字和0 到 200之间的年龄.

+ +
Person = function(name,age) {
+  this.watch("age", Person.prototype._isValidAssignment);
+  this.watch("name", Person.prototype._isValidAssignment);
+  this.name = name;
+  this.age = age;
+}
+
+Person.prototype.toString = function() {
+  return this.name + ", " + this.age;
+};
+
+Person.prototype._isValidAssignment = function(id, oldval, newval) {
+  if (id === "name" && (!newval || newval.length > 30)) {
+    throw new RangeError("不合法的名字 " + this);
+  }
+  if (id === "age"  && (newval < 0 || newval > 200)) {
+    throw new RangeError("不合法的年龄 " + this);
+  }
+  return newval;
+}
+
+will = new Person("Will", 29);
+print(will);   // Will, 29
+
+try {
+  will.name = "";
+} catch (e) {
+  //print(e);
+  console.log(e);
+}
+
+try {
+  will.age = -4;
+} catch (e) {
+  console.log(e);
+}
+
+ +

上面的代码显示结果如下:

+ +
Will, 29
+RangeError: 不合法的名字 Will, 29
+RangeError: 不合法的年龄 Will, 29
+
+ +

Specifications

+ +

不是任何规范的一部分。从 JavaScript 1.2 开始实现。

+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

兼容性提示

+ + + +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/parallelarray/index.html b/files/zh-cn/web/javascript/reference/global_objects/parallelarray/index.html new file mode 100644 index 0000000000..739d25c173 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/parallelarray/index.html @@ -0,0 +1,53 @@ +--- +title: ParallelArray +slug: Web/JavaScript/Reference/Global_Objects/ParallelArray +tags: + - JavaScript + - ParallelArray + - 过时 +translation_of: Archive/Web/ParallelArray +--- +

The goal of ParallelArray was to enable data-parallelism in web applications. The higher-order functions available on ParallelArray attempted to execute in parallel, though they may fall back to sequential execution if necessary. To ensure that your code executes in parallel, it is suggested that the functions should be limited to the parallelizable subset of JS that Firefox supports.

+ +

语法

+ +
new ParallelArray()
+new ParallelArray([element0, element1, ...])
+new ParallelArray(arrayLength, elementalFunction)
+ +

ParallelArray instances

+ +

属性

+ +
+
length
+
Reflects the number of elements in the ParallelArray.
+
+ +

方法

+ +
+
map
+
reduce
+
scan
+
scatter
+
filter
+
flatten
+
partition
+
get
+
+ +

示例

+ +

Using map in parallel

+ +
var p = new ParallelArray([0, 1, 2, 3, 4]);
+var m = p.map(function (v) {
+  return v + 1;
+});
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/parsefloat/index.html b/files/zh-cn/web/javascript/reference/global_objects/parsefloat/index.html new file mode 100644 index 0000000000..6469340da8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/parsefloat/index.html @@ -0,0 +1,123 @@ +--- +title: parseFloat +slug: Web/JavaScript/Reference/Global_Objects/parseFloat +tags: + - parseFloat() +translation_of: Web/JavaScript/Reference/Global_Objects/parseFloat +--- +
+
+
{{jsSidebar("Objects")}}
+
+
+ +

parseFloat() 函数解析一个参数(必要时先转换为字符串)并返回一个浮点数。

+ +
{{EmbedInteractiveExample("pages/js/globalprops-parsefloat.html")}}
+ +

语法

+ +
parseFloat(string)
+ +

参数

+ +
+
string
+
需要被解析成为浮点数的值。
+
+ +

返回值

+ +
+
给定值被解析成浮点数。如果给定值不能被转换成数值,则会返回 {{jsxref("NaN")}}。
+
+ +

描述

+ +

parseFloat是个全局函数,不属于任何对象。

+ + + +

考虑使用 {{jsxref("Number", "Number(value)")}} 进行更严谨的解析,只要参数带有无效字符就会被转换为 {{jsxref("NaN")}} 。

+ +

parseFloat 也可以转换一个已经定义了 toString 或者 valueOf 方法的对象,它返回的值和在调用该方法的结果上调用 parseFloat 值相同。

+ +

例子

+ +

例子: parseFloat返回正常数字

+ +

下面的例子都返回3.14

+ +
parseFloat(3.14);
+parseFloat('3.14');
+parseFloat('  3.14  ');
+parseFloat('314e-2');
+parseFloat('0.0314E+2');
+parseFloat('3.14some non-digit characters');
+parseFloat({ toString: function() { return "3.14" } });
+ +

parseFloat返回NaN

+ +

下面的例子将返回NaN

+ +
parseFloat("FF2");
+
+ +

parseFloat 和 BigInt

+ +

以下例子均返回 900719925474099300,当整数太大以至于不能被转换时将失去精度。

+ +
parseFloat(900719925474099267n);
+parseFloat('900719925474099267n');
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.1.2.3', 'parseFloat')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-parsefloat-string', 'parseFloat')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-parsefloat-string', 'parseFloat')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.parseFloat")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/parseint/index.html b/files/zh-cn/web/javascript/reference/global_objects/parseint/index.html new file mode 100644 index 0000000000..a3bfd18199 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/parseint/index.html @@ -0,0 +1,227 @@ +--- +title: parseInt +slug: Web/JavaScript/Reference/Global_Objects/parseInt +tags: + - JavaScript + - parseInt() +translation_of: Web/JavaScript/Reference/Global_Objects/parseInt +--- +
+
+
{{jsSidebar("Objects")}}
+
+
+ +

parseInt(string, radix 解析一个字符串并返回指定基数的十进制整数, radix 是2-36之间的整数,表示被解析字符串的基数。

+ +

{{EmbedInteractiveExample("pages/js/globalprops-parseint.html")}}

+ + + +

语法

+ +
parseInt(string, radix);
+ +

参数

+ +
+
string
+
要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用  ToString 抽象操作)。字符串开头的空白符将会被忽略。
+
+ +
+
radix {{optional_inline}}
+
236,表示字符串的基数。例如指定 16 表示被解析值是十六进制数。请注意,10不是默认值!
+
文章后面的描述解释了当参数 radix 不传时该函数的具体行为。
+
+ +

返回值

+ +

从给定的字符串中解析出的一个整数。

+ +

或者 {{jsxref("NaN")}},当

+ + + +
parseInt('123', 5) // 将'123'看作5进制数,返回十进制数38 => 1*5^2 + 2*5^1 + 3*5^0 = 38
+ +

描述

+ +

parseInt函数将其第一个参数转换为一个字符串,对该字符串进行解析,然后返回一个整数或 NaN

+ +

如果不是NaN,返回值将是以第一个参数作为指定基数 radix 的转换后的十进制整数。(例如,radix10,就是可以转换十进制数,为8可以转换八进制数"07",16可以转换十六进制数"0xff",以此类推)。

+ +

对于 radix 10以上的,英文字母表示大于9的数字。例如,对于十六进制数(基数16),则使用 AF

+ +

如果 parseInt 遇到的字符不是指定 radix 参数中的数字,它将忽略该字符以及所有后续字符,并返回到该点为止已解析的整数值。 parseInt 将数字截断为整数值。 允许前导和尾随空格。

+ +

由于某些数字在其字符串表示形式中使用e字符(例如 6.022×23 表示 6.022e23 ),因此当对非常大或非常小的数字使用数字时,使用 parseInt 截断数字将产生意外结果。 parseInt不应替代{{jsxref("Math.floor()")}}。

+ +


+ parseInt 可以理解两个符号。+ 表示正数,- 表示负数(从ECMAScript 1开始)。它是在去掉空格后作为解析的初始步骤进行的。如果没有找到符号,算法将进入下一步;否则,它将删除符号,并对字符串的其余部分进行数字解析。

+ +

如果 radix 是 undefined0或未指定的,JavaScript会假定以下情况:

+ +
    +
  1. 如果输入的 string以 "0x"或 "0x"(一个0,后面是小写或大写的X)开头,那么radix被假定为16,字符串的其余部分被当做十六进制数去解析。
  2. +
  3. 如果输入的 string以 "0"(0)开头, radix被假定为8(八进制)或10(十进制)。具体选择哪一个radix取决于实现。ECMAScript 5 澄清了应该使用 10 (十进制),但不是所有的浏览器都支持。因此,在使用 parseInt 时,一定要指定一个 radix
  4. +
  5. 如果输入的 string 以任何其他值开头, radix10 (十进制)。
  6. +
+ +

如果第一个字符不能转换为数字,parseInt会返回 NaN

+ +

为了算术的目的,NaN 值不能作为任何 radix 的数字。你可以调用{{jsxref("isNaN")}}函数来确定parseInt的结果是否为 NaN。如果将NaN传递给算术运算,则运算结果也将是 NaN

+ +

要将一个数字转换为特定的 radix 中的字符串字段,请使用 thatNumber.toString(radix)函数。

+ +
+

{{jsxref("BigInt")}}。警告: parseInt将 {{jsxref("BigInt")}}转换为{{jsxref("Number")}},并在这个过程中失去了精度。这是因为拖尾的非数字值,包括 "n",会被丢弃。

+
+ +

示例

+ +

例子:使用 parseInt

+ +

以下例子均返回15:

+ +
parseInt("0xF", 16);
+parseInt("F", 16);
+parseInt("17", 8);
+parseInt(021, 8);
+parseInt("015", 10);   // parseInt(015, 8); 返回 13
+parseInt(15.99, 10);
+parseInt("15,123", 10);
+parseInt("FXX123", 16);
+parseInt("1111", 2);
+parseInt("15 * 3", 10);
+parseInt("15e2", 10);
+parseInt("15px", 10);
+parseInt("12", 13);
+ +

以下例子均返回 NaN:

+ +
parseInt("Hello", 8); // 根本就不是数值
+parseInt("546", 2);   // 除了“0、1”外,其它数字都不是有效二进制数字
+
+ +

以下例子均返回 -15

+ +
parseInt("-F", 16);
+parseInt("-0F", 16);
+parseInt("-0XF", 16);
+parseInt(-15.1, 10);
+parseInt(" -17", 8);
+parseInt(" -15", 10);
+parseInt("-1111", 2);
+parseInt("-15e1", 10);
+parseInt("-12", 13);
+
+ +

下例中全部返回 4:

+ +
parseInt(4.7, 10);
+parseInt(4.7 * 1e22, 10); // 非常大的数值变成 4
+parseInt(0.00000000000434, 10); // 非常小的数值变成 4
+ +

下面的例子返回 224

+ +
parseInt("0e0",16);
+ +

没有指定 radix 参数时的八进制解析

+ +

尽管 ECMAScript 3 已经不赞成这种做法,且 ECMAScript 5 已经禁止了这种做法,但是仍然有很多实现环境仍然把以 0 开头的数值字符串(numeric string)解释为一个八进制数。下面的例子可能返回八进制的结果,也可能返回十进制的结果。总是指定一个基数(radix)可以避免这种不可靠的行为。

+ +
parseInt("0e0");
+// 0
+
+parseInt("08");
+// 0, '8' 不是八进制数字.
+
+ +

ECMAScript 5 移除了八进制解析

+ +

ECMAScript 5 规范不再允许parseInt函数的实现环境把以0字符开始的字符串作为八进制数值。ECMAScript 5 陈述如下:

+ +

根据给定radix,parseInt函数产生一个由字符串参数内容解析过来的整数值。字符串中开头的空白会被忽略。如果radix没有指定或者为0,参数会被假定以10为基数来解析,如果数值以字符对0x或0X开头,会假定以16为基数来解析。

+ +

这与ECMAScript 3有所不同,ECMAScript 3仅仅是不提倡这种做法但并没有禁止这种做法。

+ +

直至2013年,很多实现环境并没有采取新的规范所规定的做法, 而且由于必须兼容旧版的浏览器,所以永远都要明确给出radix参数的值.

+ +

一个更严格的解析函数

+ +

有时采用一个更严格的方法来解析整型值很有用。此时可以使用正则表达式:

+ +
filterInt = function (value) {
+  if(/^(\-|\+)?([0-9]+|Infinity)$/.test(value))
+    return Number(value);
+  return NaN;
+}
+
+console.log(filterInt('421'));               // 421
+console.log(filterInt('-421'));              // -421
+console.log(filterInt('+421'));              // 421
+console.log(filterInt('Infinity'));          // Infinity
+console.log(filterInt('421e+0'));            // NaN
+console.log(filterInt('421hop'));            // NaN
+console.log(filterInt('hop1.61803398875'));  // NaN
+console.log(filterInt('1.61803398875'));     // NaN
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.1.2.2', 'parseInt')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-parseint-string-radix', 'parseInt')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-parseint-string-radix', 'parseInt')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.parseInt")}}

+ +
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/all/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/all/index.html new file mode 100644 index 0000000000..84264ce68b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/all/index.html @@ -0,0 +1,224 @@ +--- +title: Promise.all() +slug: Web/JavaScript/Reference/Global_Objects/Promise/all +tags: + - AJAX + - Async-Await + - Fetch + - Promise + - Promise.all() + - Promise.race() + - promise.all +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/all +--- +
{{JSRef}}
+ +

Promise.all(iterable) 方法返回一个 {{jsxref("Promise")}} 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中  promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise 的结果。

+ +

它通常在启动多个异步任务并发运行并为其结果创建承诺之后使用,以便人们可以等待所有任务完成。

+ +
{{EmbedInteractiveExample("pages/js/promise-all.html")}}
+ + + +

语法

+ +
Promise.all(iterable);
+ +

参数

+ +
+
iterable
+
一个可迭代对象,如 {{jsxref("Array")}} 或 {{jsxref("String")}}。
+
+ +

返回值

+ + + +

说明

+ +

此方法在集合多个 promise 的返回结果时很有用。

+ +

完成(Fulfillment):
+ 如果传入的可迭代对象为空,Promise.all 会同步地返回一个已完成(resolved)状态的promise
+ 如果所有传入的 promise 都变为完成状态,或者传入的可迭代对象内没有 promisePromise.all 返回的 promise 异步地变为完成。
+ 在任何情况下,Promise.all 返回的 promise 的完成状态的结果都是一个数组,它包含所有的传入迭代参数对象的值(也包括非 promise 值)。

+ +

失败/拒绝(Rejection):
+ 如果传入的 promise 中有一个失败(rejected),Promise.all 异步地将失败的那个结果给失败状态的回调函数,而不管其它 promise 是否完成。

+ +

示例

+ +

Promise.all 的使用

+ +

Promise.all 等待所有都完成(或第一个失败)。

+ +
var p1 = Promise.resolve(3);
+var p2 = 1337;
+var p3 = new Promise((resolve, reject) => {
+  setTimeout(resolve, 100, 'foo');
+});
+
+Promise.all([p1, p2, p3]).then(values => {
+  console.log(values); // [3, 1337, "foo"]
+});
+ +

如果参数中包含非 promise 值,这些值将被忽略,但仍然会被放在返回数组中(如果 promise 完成的话):

+ +
// this will be counted as if the iterable passed is empty, so it gets fulfilled
+var p = Promise.all([1,2,3]);
+// this will be counted as if the iterable passed contains only the resolved promise with value "444", so it gets fulfilled
+var p2 = Promise.all([1,2,3, Promise.resolve(444)]);
+// this will be counted as if the iterable passed contains only the rejected promise with value "555", so it gets rejected
+var p3 = Promise.all([1,2,3, Promise.reject(555)]);
+
+// using setTimeout we can execute code after the stack is empty
+setTimeout(function(){
+    console.log(p);
+    console.log(p2);
+    console.log(p3);
+});
+
+// logs
+// Promise { <state>: "fulfilled", <value>: Array[3] }
+// Promise { <state>: "fulfilled", <value>: Array[4] }
+// Promise { <state>: "rejected", <reason>: 555 }
+ +

Promise.all 的异步和同步

+ +

下面的例子中演示了 Promise.all 的异步性(如果传入的可迭代对象是空的,就是同步):

+ +
// we are passing as argument an array of promises that are already resolved,
+// to trigger Promise.all as soon as possible
+var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];
+
+var p = Promise.all(resolvedPromisesArray);
+// immediately logging the value of p
+console.log(p);
+
+// using setTimeout we can execute code after the stack is empty
+setTimeout(function(){
+    console.log('the stack is now empty');
+    console.log(p);
+});
+
+// logs, in order:
+// Promise { <state>: "pending" }
+// the stack is now empty
+// Promise { <state>: "fulfilled", <value>: Array[2] }
+
+ +

如果 Promise.all 失败,也是一样的:

+ +
var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44)];
+var p = Promise.all(mixedPromisesArray);
+console.log(p);
+setTimeout(function(){
+    console.log('the stack is now empty');
+    console.log(p);
+});
+
+// logs
+// Promise { <state>: "pending" }
+// the stack is now empty
+// Promise { <state>: "rejected", <reason>: 44 }
+
+ +

但是,Promise.all 当且仅当传入的可迭代对象为空时为同步:

+ +
var p = Promise.all([]); // will be immediately resolved
+var p2 = Promise.all([1337, "hi"]); // non-promise values will be ignored, but the evaluation will be done asynchronously
+console.log(p);
+console.log(p2)
+setTimeout(function(){
+    console.log('the stack is now empty');
+    console.log(p2);
+});
+
+// logs
+// Promise { <state>: "fulfilled", <value>: Array[0] }
+// Promise { <state>: "pending" }
+// the stack is now empty
+// Promise { <state>: "fulfilled", <value>: Array[2] }
+
+ +

Promise.all 的快速返回失败行为

+ +

Promise.all 在任意一个传入的 promise 失败时返回失败。例如,如果你传入的 promise中,有四个 promise 在一定的时间之后调用成功函数,有一个立即调用失败函数,那么 Promise.all 将立即变为失败。

+ +
var p1 = new Promise((resolve, reject) => {
+  setTimeout(resolve, 1000, 'one');
+});
+var p2 = new Promise((resolve, reject) => {
+  setTimeout(resolve, 2000, 'two');
+});
+var p3 = new Promise((resolve, reject) => {
+  setTimeout(resolve, 3000, 'three');
+});
+var p4 = new Promise((resolve, reject) => {
+  setTimeout(resolve, 4000, 'four');
+});
+var p5 = new Promise((resolve, reject) => {
+  reject('reject');
+});
+
+Promise.all([p1, p2, p3, p4, p5]).then(values => {
+  console.log(values);
+}, reason => {
+  console.log(reason)
+});
+
+//From console:
+//"reject"
+
+//You can also use .catch
+Promise.all([p1, p2, p3, p4, p5]).then(values => {
+  console.log(values);
+}).catch(reason => {
+  console.log(reason)
+});
+
+//From console:
+//"reject"
+
+
+ +

技术规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-promise.all', 'Promise.all')}}{{Spec2('ES2015')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-promise.all', 'Promise.all')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Promise.all")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/allsettled/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/allsettled/index.html new file mode 100644 index 0000000000..de674edc7f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/allsettled/index.html @@ -0,0 +1,73 @@ +--- +title: Promise.allSettled() +slug: Web/JavaScript/Reference/Global_Objects/Promise/allSettled +tags: + - Promise + - Promise.allSettled + - promise.all +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/allSettled +--- +

{{JSRef}}

+ +

Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilledrejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。

+ +

当您有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个promise的结果时,通常使用它。

+ +

相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时立即结束。

+ +
{{EmbedInteractiveExample("pages/js/promise-allsettled.html")}}
+ +

句法

+ +
Promise.allSettled(iterable);
+ +

参数

+ +
+
iterable
+
一个可迭代的对象,例如{{jsxref("Array")}},其中每个成员都是Promise
+
+ +

返回值

+ +

一旦所指定的 promises 集合中每一个 promise 已经完成,无论是成功的达成或被拒绝,未决议的 {{jsxref("Promise")}}将被异步完成。那时,所返回的 promise 的处理器将传入一个数组作为输入,该数组包含原始 promises 集中每个 promise 的结果。

+ +

对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason 。value(或 reason )反映了每个 promise 决议(或拒绝)的值。

+ +

标准

+ + + + + + + + + + + + + + +
规格状态评论
Promise.allSettled() (TC39第4阶段草案){{SPEC2("ESDraft")}}
+ +

浏览器兼容

+ +

{{Compat("javascript.builtins.Promise.allSettled")}}

+ +

实现进度

+ +

{{EmbedTest262ReportResultsTable("Promise.allSettled")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/any/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/any/index.html new file mode 100644 index 0000000000..25e87a91af --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/any/index.html @@ -0,0 +1,153 @@ +--- +title: Promise.any() +slug: Web/JavaScript/Reference/Global_Objects/Promise/any +tags: + - Experimental + - JavaScript + - Method + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/any +--- +

{{JSRef}}

+ +

Promise.any() 接收一个{{JSxRef("Promise")}}可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和{{JSxRef("Global_Objects/AggregateError", "AggregateError")}}类型的实例,它是 {{JSxRef("Error")}} 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和{{JSxRef("Promise.all()")}}是相反的。

+ +
+

注意! Promise.any() 方法依然是实验性的,尚未被所有的浏览器完全支持。它当前处于 TC39 第四阶段草案(Stage 4)

+
+ +

语法

+ +
Promise.any(iterable);
+ +

参数

+ +
+
iterable
+
一个可迭代的对象, 例如 Array
+
+ +

返回值

+ + + +

说明

+ +

这个方法用于返回第一个成功的 promise 。只要有一个 promise 成功此方法就会终止,它不会等待其他的 promise 全部完成。

+ +

不像 Promise.all() 会返回一组完成值那样(resolved values),我们只能得到一个成功值(假设至少有一个 promise 完成)。当我们只需要一个 promise 成功,而不关心是哪一个成功时此方法很有用的。

+ +

同时, 也不像 Promise.race() 总是返回第一个结果值(resolved/reject)那样,这个方法返回的是第一个 成功的 值。这个方法将会忽略掉所有被拒绝的 promise,直到第一个 promise 成功。

+ +

成功(Fulfillment):

+ +

当任何一个被传入的 promise 成功的时候, 无论其他的 promises 成功还是失败,此函数会将那个成功的 promise 作为返回值 。

+ + + +

失败/拒绝(Rejection):

+ +

如果所有传入的 promises 都失败, Promise.any 将返回异步失败,和一个 AggregateError 对象,它继承自 Error,有一个 error 属性,属性值是由所有失败值填充的数组。

+ +

示例

+ +

First to fulfil

+ +

即使第一个返回的 promise 是失败的,Promise.any() 依然使用第一个成功状态的 promise 来返回。这与使用首个(无论 rejected 还是 fullfiled)promise 来返回的 {{jsxref("Promise.race()")}} 相反。

+ +
const pErr = new Promise((resolve, reject) => {
+  reject("总是失败");
+});
+
+const pSlow = new Promise((resolve, reject) => {
+  setTimeout(resolve, 500, "最终完成");
+});
+
+const pFast = new Promise((resolve, reject) => {
+  setTimeout(resolve, 100, "很快完成");
+});
+
+Promise.any([pErr, pSlow, pFast]).then((value) => {
+  console.log(value);
+  // pFast fulfils first
+})
+// 期望输出: "很快完成"
+
+ +

Rejections with AggregateError

+ +

如果没有 fulfilled (成功的) promise,Promise.any() 返回 {{jsxref("AggregateError")}} 错误。

+ +
const pErr = new Promise((resolve, reject) => {
+  reject('总是失败');
+});
+
+Promise.any([pErr]).catch((err) => {
+  console.log(err);
+})
+// 期望输出: "AggregateError: No Promise in Promise.any was resolved"
+
+ +

显示第一张已加载的图片

+ +

在这个例子,我们有一个获取图片并返回 blob 的函数,我们使用 Promise.any() 来获取一些图片并显示第一张有效的图片(即最先 resolved 的那个 promise)。

+ +
function fetchAndDecode(url) {
+  return fetch(url).then(response => {
+    if(!response.ok) {
+      throw new Error(`HTTP error! status: ${response.status}`);
+    } else {
+      return response.blob();
+    }
+  })
+}
+
+let coffee = fetchAndDecode('coffee.jpg');
+let tea = fetchAndDecode('tea.jpg');
+
+Promise.any([coffee, tea]).then(value => {
+  let objectURL = URL.createObjectURL(value);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+})
+.catch(e => {
+  console.log(e.message);
+});
+ +

规范

+ + + + + + + + + + + + +
规范
{{SpecName('Promise.any')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Promise.any")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/catch/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/catch/index.html new file mode 100644 index 0000000000..3bd0a41fd4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/catch/index.html @@ -0,0 +1,156 @@ +--- +title: Promise.prototype.catch() +slug: Web/JavaScript/Reference/Global_Objects/Promise/catch +tags: + - Promise + - Promise.prototype.catch() +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/catch +--- +
{{JSRef}}
+ +

catch() 方法返回一个Promise,并且处理拒绝的情况。它的行为与调用{{jsxref("Promise.then", "Promise.prototype.then(undefined, onRejected)")}} 相同。 (事实上, calling obj.catch(onRejected) 内部calls obj.then(undefined, onRejected)).

+ +

语法

+ +
p.catch(onRejected);
+
+p.catch(function(reason) {
+   // 拒绝
+});
+
+ +

参数

+ +
+
onRejected
+
当Promise 被rejected时,被调用的一个{{jsxref("Function")}}。 该函数拥有一个参数:
+
reason    rejection 的原因。
+
+

 如果 onRejected 抛出一个错误或返回一个本身失败的 Promise ,  通过 catch() 返回的Promise 被rejected;否则,它将显示为成功(resolved)。 

+ +

返回值

+ +

一个{{jsxref("Promise")}}.

+
+
+ +

描述

+ +

catch 方法可以用于您的promise组合中的错误处理。

+ +

Internally calls Promise.prototype.then on the object upon which is called, passing the parameters undefined and the onRejected handler received; then returns the value of that call (which is a {{jsxref("Promise")}}).

+ +

示例

+ +

使用链式语句的 catch方法

+ +
var p1 = new Promise(function(resolve, reject) {
+  resolve('Success');
+});
+
+p1.then(function(value) {
+  console.log(value); // "Success!"
+  throw 'oh, no!';
+}).catch(function(e) {
+  console.log(e); // "oh, no!"
+}).then(function(){
+  console.log('after a catch the chain is restored');
+}, function () {
+  console.log('Not fired due to the catch');
+});
+
+// 以下行为与上述相同
+p1.then(function(value) {
+  console.log(value); // "Success!"
+  return Promise.reject('oh, no!');
+}).catch(function(e) {
+  console.log(e); // "oh, no!"
+}).then(function(){
+  console.log('after a catch the chain is restored');
+}, function () {
+  console.log('Not fired due to the catch');
+});
+ +

捕获抛出的错误

+ +
// 抛出一个错误,大多数时候将调用catch方法
+var p1 = new Promise(function(resolve, reject) {
+  throw 'Uh-oh!';
+});
+
+p1.catch(function(e) {
+  console.log(e); // "Uh-oh!"
+});
+
+// 在异步函数中抛出的错误不会被catch捕获到
+var p2 = new Promise(function(resolve, reject) {
+  setTimeout(function() {
+    throw 'Uncaught Exception!';
+  }, 1000);
+});
+
+p2.catch(function(e) {
+  console.log(e); // 不会执行
+});
+
+// 在resolve()后面抛出的错误会被忽略
+var p3 = new Promise(function(resolve, reject) {
+  resolve();
+  throw 'Silenced Exception!';
+});
+
+p3.catch(function(e) {
+   console.log(e); // 不会执行
+});
+ +

如果已决议

+ +
//创建一个新的 Promise ,且已决议
+var p1 = Promise.resolve("calling next");
+
+var p2 = p1.catch(function (reason) {
+    //这个方法永远不会调用
+    console.log("catch p1!");
+    console.log(reason);
+});
+
+p2.then(function (value) {
+    console.log("next promise's onFulfilled"); /* next promise's onFulfilled */
+    console.log(value); /* calling next */
+}, function (reason) {
+    console.log("next promise's onRejected");
+    console.log(reason);
+});
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
domenic/promises-unwrapping{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ES6', '#sec-promise.prototype.catch', 'Promise.prototype.catch')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{Compat("javascript/promise","Promise.prototype.catch")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/finally/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/finally/index.html new file mode 100644 index 0000000000..6f0711e765 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/finally/index.html @@ -0,0 +1,101 @@ +--- +title: Promise.prototype.finally() +slug: Web/JavaScript/Reference/Global_Objects/Promise/finally +tags: + - JavaScript + - Promises + - Reference + - finally +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/finally +--- +
{{JSRef}}
+ +
+ +
finally() 方法返回一个{{jsxref("Promise")}}。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。
+ +
这避免了同样的语句需要在{{jsxref("Promise.then", "then()")}}和{{jsxref("Promise.catch", "catch()")}}中各写一次的情况。
+ +

语法

+ +
p.finally(onFinally);
+
+p.finally(function() {
+   // 返回状态为(resolved 或 rejected)
+});
+ +

参数

+ +
+
onFinally
+
Promise 结束后调用的{{jsxref("Function")}}。
+
+ +

返回值

+ +

返回一个设置了 finally 回调函数的{{jsxref("Promise")}}对象。 

+ +

描述

+ +

如果你想在 promise 执行完毕后无论其结果怎样都做一些处理或清理时,finally() 方法可能是有用的。

+ +

finally() 虽然与 .then(onFinally, onFinally) 类似,它们不同的是:

+ + + +
+

注意: 在finally回调中 throw(或返回被拒绝的promise)将以 throw() 指定的原因拒绝新的promise.

+
+ +

示例

+ +
let isLoading = true;
+
+fetch(myRequest).then(function(response) {
+    var contentType = response.headers.get("content-type");
+    if(contentType && contentType.includes("application/json")) {
+      return response.json();
+    }
+    throw new TypeError("Oops, we haven't got JSON!");
+  })
+  .then(function(json) { /* process your JSON further */ })
+  .catch(function(error) { console.log(error); })
+  .finally(function() { isLoading = false; });
+
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-promise.prototype.finally', 'Promise.prototype.finally')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Promise.finally")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/index.html new file mode 100644 index 0000000000..5378fe3aeb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/index.html @@ -0,0 +1,311 @@ +--- +title: Promise +slug: Web/JavaScript/Reference/Global_Objects/Promise +tags: + - ECMAScript 2015 + - ES6 + - JavaScript + - Promise + - Promise A+ + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise +--- +

{{JSRef}}

+ +

Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。

+ +

若想了解 promises 的工作方式以及如何使用它们,我们建议您先阅读使用 promises

+ +

描述

+ +

一个 Promise 对象代表一个在这个 promise 被创建出来时不一定已知的值。它让您能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。 这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。

+ +

一个 Promise 必然处于以下几种状态之一:

+ + + +

待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个原因(错误)被拒绝(rejected)。当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序就会被调用,因此在完成异步操作和绑定处理方法之间不会存在竞争状态。

+ +

因为 {{jsxref("Promise.then", "Promise.prototype.then")}} 和  {{jsxref("Promise.catch", "Promise.prototype.catch")}} 方法返回的是 promise, 所以它们可以被链式调用。

+ +

+ +
+

不要和惰性求值混淆: 有一些语言中有惰性求值和延时计算的特性,它们也被称为“promises”,例如 Scheme。JavaScript 中的 promise 代表的是已经正在发生的进程, 而且可以通过回调函数实现链式调用。 如果您想对一个表达式进行惰性求值,就考虑一下使用无参数的"箭头函数":  f = () =>表达式 来创建惰性求值的表达式使用 f() 求值。

+
+ +
+

注意: 如果一个 promise 已经被兑现(fulfilled)或被拒绝(rejected),那么我们也可以说它处于已敲定(settled)状态。您还会听到一个经常跟 promise 一起使用的术语:已决议(resolved),它表示 promise 已经处于已敲定(settled)状态,或者为了匹配另一个 promise 的状态被"锁定"了。Domenic Denicola 的 States and fates 中有更多关于 promise 术语的细节可以供您参考。

+
+ +

Promise的链式调用

+ +

我们可以用 promise.then()promise.catch()promise.finally() 这些方法将进一步的操作与一个变为已敲定状态的 promise 关联起来。这些方法还会返回一个新生成的 promise 对象,这个对象可以被非强制性的用来做链式调用,就像这样:

+ +
const myPromise =
+  (new Promise(myExecutorFunc))
+  .then(handleFulfilledA,handleRejectedA)
+  .then(handleFulfilledB,handleRejectedB)
+  .then(handleFulfilledC,handleRejectedC);
+
+// 或者,这样可能会更好...
+
+const myPromise =
+  (new Promise(myExecutorFunc))
+  .then(handleFulfilledA)
+  .then(handleFulfilledB)
+  .then(handleFulfilledC)
+  .catch(handleRejectedAny);
+ +

过早地处理被拒绝的 promise 会对之后 promise 的链式调用造成影响。不过有时候我们因为需要马上处理一个错误也只能这样做。(有关应对影响的技巧,请参见下面示例中的 throw -999 )另一方面,在没有迫切需要的情况下,可以在最后一个.catch() 语句时再进行错误处理,这种做法更加简单。

+ +

这两个函数的签名很简单,它们只接受一个任意类型的参数。这些函数由您(编程者)编写。这些函数的终止状态决定着链式调用中下一个promise的"已敲定 (settled)"状态是什么。任何不是 throw 的终止都会创建一个"已决议(resolved)"状态,而以 throw 终止则会创建一个"已拒绝"状态。

+ +
handleFulfilled(value)       { /*...*/; return nextValue;  }
+handleRejection(reason)  { /*...*/; throw  nextReason; }
+handleRejection(reason)  { /*...*/; return nextValue;  }
+ +

被返回的 nextValue 可能是另一个promise对象,这种情况下这个promise会被动态地插入链式调用。 

+ +

.then() 中缺少能够返回 promise 对象的函数时,链式调用就直接继续进行下一环操作。因此,链式调用可以在最后一个 .catch() 之前把所有的 handleRejection 都省略掉。类似地, .catch() 其实只是没有给 handleFulfilled 预留参数位置的 .then() 而已。

+ +

链式调用中的 promise 们就像俄罗斯套娃一样,是嵌套起来的,但又像是一个栈,每个都必须从顶端被弹出。链式调用中的第一个 promise 是嵌套最深的一个,也将是第一个被弹出的。

+ +
(promise D, (promise C, (promise B, (promise A) ) ) )
+ +

当存在一个 nextValue 是 promise 时,就会出现一种动态的替换效果。return 会导致一个 promise 被弹出,但这个 nextValue promise 则会被推入被弹出 promise 原来的位置。对于上面所示的嵌套场景,假设与 "promise B" 相关的 .then() 返回了一个值为 "promise X" 的 nextValue 。那么嵌套的结果看起来就会是这样:

+ +
(promise D, (promise C, (promise X) ) )
+ +

一个 promise 可能会参与不止一次的嵌套。对于下面的代码,promiseA 向"已敲定"("settled")状态的过渡会导致两个实例的 .then 都被调用。

+ +
const promiseA = new Promise(myExecutorFunc);
+const promiseB = promiseA.then(handleFulfilled1, handleRejected1);
+const promiseC = promiseA.then(handleFulfilled2, handleRejected2); 
+ +

一个已经处于"已敲定"("settled")状态的 promise 也可以接收操作。在那种情况下,(如果没有问题的话,)这个操作会被作为第一个异步操作被执行。注意,所有的 promise 都一定是异步的。因此,一个已经处于"已敲定"("settled")状态的 promise 中的操作只有 promise 链式调用的栈被清空了和一个事件循环过去了之后才会被执行。这种效果跟 setTimeout(action, 10) 特别相似。

+ +
const promiseA = new Promise( (resolutionFunc,rejectionFunc) => {
+    resolutionFunc(777);
+});
+// 这时,"promiseA" 已经被敲定了。
+promiseA.then( (val) => console.log("asynchronous logging has val:",val) );
+console.log("immediate logging");
+
+// produces output in this order:
+// immediate logging
+// asynchronous logging has val: 777
+
+ +

构造函数

+ +
+
{{jsxref("Promise/Promise", "Promise()")}}
+
创建一个新的 Promise 对象。该构造函数主要用于包装还没有添加 promise 支持的函数。
+
+ +

静态方法

+ +
+
{{jsxref("Promise.all", "Promise.all(iterable)")}}
+
这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。(可以参考jQuery.when方法---译者注)
+
+ +
+
{{jsxref("Promise.allSettled", "Promise.allSettled(iterable)")}}
+
等到所有promises都已敲定(settled)(每个promise都已兑现(fulfilled)或已拒绝(rejected))。
+ 返回一个promise,该promise在所有promise完成后完成。并带有一个对象数组,每个对象对应每个promise的结果。
+
+ +
+
{{jsxref("Promise.any", "Promise.any(iterable)")}}
+
接收一个Promise对象的集合,当其中的一个 promise 成功,就返回那个成功的promise的值。
+
+ +
+
{{jsxref("Promise.race", "Promise.race(iterable)")}}
+
当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。
+
+ +
+
{{jsxref("Promise.reject", "Promise.reject(reason)")}}
+
返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法
+
+ +
+
{{jsxref("Promise.resolve", "Promise.resolve(value)")}}
+
返回一个状态由给定value决定的Promise对象。如果该值是thenable(即,带有then方法的对象),返回的Promise对象的最终状态由then方法执行决定;否则的话(该value为空,基本类型或者不带then方法的对象),返回的Promise对象状态为fulfilled,并且将该value传递给对应的then方法。通常而言,如果您不知道一个值是否是Promise对象,使用Promise.resolve(value) 来返回一个Promise对象,这样就能将该value以Promise对象形式使用。
+
+ +

Promise 原型

+ +

属性

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/Promise/prototype','属性')}}

+ +

方法

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/Promise/prototype','方法')}}

+ +

创建Promise

+ +

Promise 对象是由关键字 new 及其构造函数来创建的。该构造函数会把一个叫做“处理器函数”(executor function)的函数作为它的参数。这个“处理器函数”接受两个函数——resolve 和 reject ——作为其参数。当异步任务顺利完成且返回结果值时,会调用 resolve 函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject 函数。

+ +
const myFirstPromise = new Promise((resolve, reject) => {
+  // ?做一些异步操作,最终会调用下面两者之一:
+  //
+  //   resolve(someValue); // fulfilled
+  // ?或
+  //   reject("failure reason"); // rejected
+});
+ +

想要某个函数拥有promise功能,只需让其返回一个promise即可。

+ +
function myAsyncFunction(url) {
+  return new Promise((resolve, reject) => {
+    const xhr = new XMLHttpRequest();
+    xhr.open("GET", url);
+    xhr.onload = () => resolve(xhr.responseText);
+    xhr.onerror = () => reject(xhr.statusText);
+    xhr.send();
+  });
+};
+ +

示例

+ +

基础示例

+ +
let myFirstPromise = new Promise(function(resolve, reject){
+    //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
+    //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
+    setTimeout(function(){
+        resolve("成功!"); //代码正常执行!
+    }, 250);
+});
+
+myFirstPromise.then(function(successMessage){
+    //successMessage的值是上面调用resolve(...)方法传入的值.
+    //successMessage参数不一定非要是字符串类型,这里只是举个例子
+    console.log("Yay! " + successMessage);
+});
+
+ +

高级示例

+ + + +

本例展示了 Promise 的一些机制。 testPromise() 方法在每次点击 {{HTMLElement("button")}} 按钮时被调用,该方法会创建一个promise 对象,使用 {{domxref("window.setTimeout()")}} 让Promise等待 1-3 秒不等的时间来填充数据(通过Math.random()方法)。

+ +

Promise 的值的填充过程都被日志记录(logged)下来,这些日志信息展示了方法中的同步代码和异步代码是如何通过Promise完成解耦的。

+ +
'use strict';
+var promiseCount = 0;
+
+function testPromise() {
+    let thisPromiseCount = ++promiseCount;
+
+    let log = document.getElementById('log');
+    log.insertAdjacentHTML('beforeend', thisPromiseCount +
+        ') 开始 (<small>同步代码开始</small>)<br/>');
+
+    // 新构建一个 Promise 实例:使用Promise实现每过一段时间给计数器加一的过程,每段时间间隔为1~3秒不等
+    let p1 = new Promise(
+        // resolver 函数在 Promise 成功或失败时都可能被调用
+       (resolve, reject) => {
+            log.insertAdjacentHTML('beforeend', thisPromiseCount +
+                ') Promise 开始 (<small>异步代码开始</small>)<br/>');
+            // 创建一个异步调用
+            window.setTimeout(
+                function() {
+                    // 填充 Promise
+                    resolve(thisPromiseCount);
+                }, Math.random() * 2000 + 1000);
+        }
+    );
+
+    // Promise 不论成功或失败都会调用 then
+    // catch() 只有当 promise 失败时才会调用
+    p1.then(
+        // 记录填充值
+        function(val) {
+            log.insertAdjacentHTML('beforeend', val +
+                ') Promise 已填充完毕 (<small>异步代码结束</small>)<br/>');
+        })
+    .catch(
+        // 记录失败原因
+       (reason) => {
+            console.log('处理失败的 promise ('+reason+')');
+        });
+
+    log.insertAdjacentHTML('beforeend', thisPromiseCount +
+        ') Promise made (<small>同步代码结束</small>)<br/>');
+}
+ + + +

点击下面的按钮可以看到示例代码运行的效果,前提是您的浏览器支持 Promise。快速点击按钮多次您会观察到Promises填充值的过程。

+ +

{{EmbedLiveSample("高级一点的例子", "500", "200")}}

+ +

使用 XHR 加载图像

+ +

另一个用了 Promise XMLHttpRequest 加载一个图像的例子可在MDN GitHub promise-test 中找到。 您也可以看这个实例。每一步都有注释可以让您详细的了解Promise和XHR架构。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-promise-objects', 'Promise')}}{{Spec2('ES2015')}}ECMA标准中的首次定义
{{SpecName('ESDraft', '#sec-promise-objects', 'Promise')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Promise")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/promise/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/promise/index.html new file mode 100644 index 0000000000..c871b52513 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/promise/index.html @@ -0,0 +1,73 @@ +--- +title: Promise() 构造器 +slug: Web/JavaScript/Reference/Global_Objects/Promise/Promise +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/Promise +--- +
{{JSRef}}
+ +

Promise 构造器主要用于包装不支持promise(返回值不是Promise)的函数。

+ +
{{EmbedInteractiveExample("pages/js/promise-constructor.html")}}
+ + + +

语法

+ +
new Promise(executor)
+ +

参数

+ +
+
executor
+
这是一个双参函数,参数为resolverejectPromise的实现会立即执行executor,并传入resolvereject函数(Promise构造器将会在返回新对象之前executor)。当resolvereject函数被调用时,它们分别对promise执行resolverejectexecutor通常会触发一些异步运算,一旦运算成功完成,则resolve掉这个promise,如果出错则reject掉。如果executor函数执行时抛出异常,promise状态会变为rejectedexecutor的返回值也会被忽略。
+
+ +

例子

+ +

我们通过new关键字和Promise构造器创建它的对象。这个构造器接受一个名为"executor function"的函数。这个函数应当接受两个函数参数。当异步任务成功时,第一个函数(resolve)将被调用,并返回一个值代表成功。当其失败时,第二个函数(reject)将被调用,并返回失败原因(失败原因通常是一个error对象)。

+ +
const myFirstPromise = new Promise((resolve, reject) => {
+  // do something asynchronous which eventually calls either:
+  //
+  //   resolve(someValue)        // fulfilled
+  // or
+  //   reject("failure reason")  // rejected
+});
+
+ +

为了提供一个拥有promise功能的函数,简单的返回一个promise即可:

+ +
function myAsyncFunction(url) {
+  return new Promise((resolve, reject) => {
+    const xhr = new XMLHttpRequest()
+    xhr.open("GET", url)
+    xhr.onload = () => resolve(xhr.responseText)
+    xhr.onerror = () => reject(xhr.statusText)
+    xhr.send()
+  });
+}
+ +

说明

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-promise-constructor', 'Promise constructor')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Promise.Promise")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/prototype/index.html new file mode 100644 index 0000000000..3b26852c87 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/prototype/index.html @@ -0,0 +1,115 @@ +--- +title: Promise.prototype +slug: Web/JavaScript/Reference/Global_Objects/Promise/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Promise +--- +
{{JSRef("Global_Objects", "Promise")}}
+ +

总结

+ +

Promise.prototype 属性表示 {{jsxref("Promise")}} 构造器的原型.

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

{{jsxref("Promise")}} 实例继承自 {{jsxref("Promise.prototype")}}. 你可以在构造器的原型对象添加属性或方法到所有 Promise 实例上.

+ +

属性

+ +
+
Promise.prototype.constructor
+
返回被创建的实例函数.  默认为 {{jsxref("Promise")}} 函数.
+
+ +

方法

+ +
+
{{jsxref("Promise.catch", "Promise.prototype.catch(onRejected)")}}
+
添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的完成结果作为新promise的完成结果.
+
{{jsxref("Promise.then", "Promise.prototype.then(onFulfilled, onRejected)")}}
+
添加解决(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve.
+
{{jsxref("Promise.finally", "Promise.prototype.finally(onFinally)")}}
+
添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support32{{CompatGeckoDesktop(24.0)}} as Future
+ {{CompatGeckoDesktop(25.0)}} as Promise behind a flag[1]
+ {{CompatGeckoDesktop(29.0)}} by default
{{CompatNo}}197.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatGeckoMobile(24.0)}} as Future
+ {{CompatGeckoMobile(25.0)}} as Promise behind a flag[1]
+ {{CompatGeckoMobile(29.0)}} by default
{{CompatNo}}{{CompatNo}}iOS 832
+
+ +

[1] Gecko 24 has an experimental implementation of Promise, under the initial name of Future. It got renamed to its final name in Gecko 25, but disabled by default behind the flag dom.promise.enabled. Bug 918806 enabled Promises by default in Gecko 29.

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/race/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/race/index.html new file mode 100644 index 0000000000..1220002fe1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/race/index.html @@ -0,0 +1,138 @@ +--- +title: Promise.race() +slug: Web/JavaScript/Reference/Global_Objects/Promise/race +tags: + - Promise +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/race +--- +
{{JSRef}}
+ +

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

+ +
{{EmbedInteractiveExample("pages/js/promise-race.html")}}
+ + + +

语法

+ +
Promise.race(iterable);
+ +

参数

+ +
+
iterable
+
可迭代对象,类似{{jsxref("Array")}}。详见 iterable
+
+ +

返回值

+ +

一个待定的 {{jsxref("Promise")}} 只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的值,从而异步地解析或拒绝(一旦堆栈为空)。

+ +

描述

+ +

race 函数返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。

+ +

如果传的迭代是空的,则返回的 promise 将永远等待。

+ +

如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则 Promise.race 将解析为迭代中找到的第一个值。

+ +

示例

+ +

Promise.race的异步性

+ +
// we are passing as argument an array of promises that are already resolved,
+// to trigger Promise.race as soon as possible
+var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];
+
+var p = Promise.race(resolvedPromisesArray);
+// immediately logging the value of p
+console.log(p);
+
+// using setTimeout we can execute code after the stack is empty
+setTimeout(function(){
+    console.log('the stack is now empty');
+    console.log(p);
+});
+
+// logs, in order:
+// Promise { <state>: "pending" }
+// the stack is now empty
+// Promise { <state>: "fulfilled", <value>: 33 }
+ +

使用 Promise.race –  setTimeout 的示例

+ +
var p1 = new Promise(function(resolve, reject) {
+    setTimeout(resolve, 500, "one");
+});
+var p2 = new Promise(function(resolve, reject) {
+    setTimeout(resolve, 100, "two");
+});
+
+Promise.race([p1, p2]).then(function(value) {
+  console.log(value); // "two"
+  // 两个都完成,但 p2 更快
+});
+
+var p3 = new Promise(function(resolve, reject) {
+    setTimeout(resolve, 100, "three");
+});
+var p4 = new Promise(function(resolve, reject) {
+    setTimeout(reject, 500, "four");
+});
+
+Promise.race([p3, p4]).then(function(value) {
+  console.log(value); // "three"
+  // p3 更快,所以它完成了
+}, function(reason) {
+  // 未被调用
+});
+
+var p5 = new Promise(function(resolve, reject) {
+    setTimeout(resolve, 500, "five");
+});
+var p6 = new Promise(function(resolve, reject) {
+    setTimeout(reject, 100, "six");
+});
+
+Promise.race([p5, p6]).then(function(value) {
+  // 未被调用
+}, function(reason) {
+  console.log(reason); // "six"
+  // p6 更快,所以它失败了
+});
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-promise.race', 'Promise.race')}}{{Spec2('ES2015')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-promise.race', 'Promise.race')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Promise.race")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/reject/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/reject/index.html new file mode 100644 index 0000000000..f5a8f82156 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/reject/index.html @@ -0,0 +1,78 @@ +--- +title: Promise.reject() +slug: Web/JavaScript/Reference/Global_Objects/Promise/reject +tags: + - ECAMScript 2015 + - JavaScript + - Method + - Promise +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/reject +--- +
{{JSRef}}
+ +

Promise.reject()方法返回一个带有拒绝原因的Promise对象。

+ +

{{EmbedInteractiveExample("pages/js/promise-reject.html")}}

+ +

语法

+ +
Promise.reject(reason);
+ +

参数

+ +
+
reason
+
表示Promise被拒绝的原因。
+
+ +

返回值

+ +
+
一个给定原因了的被拒绝的 {{jsxref("Promise")}}。
+
+ +

描述

+ +

静态函数Promise.reject返回一个被拒绝的Promise对象。通过使用{{jsxref("Error")}}的实例获取错误原因reason对调试和选择性错误捕捉很有帮助。

+ +

示例

+ +

使用静态Promise.reject()方法

+ +
Promise.reject(new Error('fail')).then(function() {
+  // not called
+}, function(error) {
+  console.error(error); // Stacktrace
+});
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-promise.reject', 'Promise.reject')}}{{Spec2('ES2015')}}ECMA规范的首次定义
{{SpecName('ESDraft', '#sec-promise.reject', 'Promise.reject')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Promise.reject")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/resolve/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/resolve/index.html new file mode 100644 index 0000000000..607fa09f36 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/resolve/index.html @@ -0,0 +1,158 @@ +--- +title: Promise.resolve() +slug: Web/JavaScript/Reference/Global_Objects/Promise/resolve +tags: + - ECMAScript 2015 + - JavaScript + - Promise +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/resolve +--- +
{{JSRef}}
+ +
Promise.resolve(value)方法返回一个以给定值解析后的{{jsxref("Promise")}} 对象。如果这个值是一个 promise ,那么将返回这个 promise ;如果这个值是thenable(即带有{{jsxref("Promise.then", "\"then\" ")}}方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。
+ +
+ +
+ +
+

警告:不要在解析为自身的thenable 上调用Promise.resolve。这将导致无限递归,因为它试图展平无限嵌套的promise。一个例子是将它与Angular中的异步管道一起使用。在此处了解更多信息。

+
+ +
{{EmbedInteractiveExample("pages/js/promise-resolve.html")}}
+ + + +

语法

+ +
Promise.resolve(value);
+
+ +

参数

+ +
+
value
+
+ +

将被Promise对象解析的参数,也可以是一个Promise对象,或者是一个thenable。

+ +

返回值

+ +

返回一个带着给定值解析过的Promise对象,如果参数本身就是一个Promise对象,则直接返回这个Promise对象。

+ +

描述

+ +

静态方法 Promise.resolve返回一个解析过的Promise对象。

+ +

示例

+ +

使用静态Promise.resolve方法

+ +
Promise.resolve("Success").then(function(value) {
+  console.log(value); // "Success"
+}, function(value) {
+  // 不会被调用
+});
+
+ +

resolve一个数组

+ +
var p = Promise.resolve([1,2,3]);
+p.then(function(v) {
+  console.log(v[0]); // 1
+});
+
+ +

resolve另一个promise

+ +
var original = Promise.resolve(33);
+var cast = Promise.resolve(original);
+cast.then(function(value) {
+  console.log('value: ' + value);
+});
+console.log('original === cast ? ' + (original === cast));
+
+/*
+*  打印顺序如下,这里有一个同步异步先后执行的区别
+*  original === cast ? true
+*  value: 33
+*/
+ +

日志顺序颠倒其实是由于异步地调用then 方法。在这里查看then 是如何工作的。

+ +

resolve thenable 并抛出错误

+ +
// Resolve一个thenable对象
+var p1 = Promise.resolve({
+  then: function(onFulfill, onReject) { onFulfill("fulfilled!"); }
+});
+console.log(p1 instanceof Promise) // true, 这是一个Promise对象
+
+p1.then(function(v) {
+    console.log(v); // 输出"fulfilled!"
+  }, function(e) {
+    // 不会被调用
+});
+
+// Thenable在callback之前抛出异常
+// Promise rejects
+var thenable = { then: function(resolve) {
+  throw new TypeError("Throwing");
+  resolve("Resolving");
+}};
+
+var p2 = Promise.resolve(thenable);
+p2.then(function(v) {
+  // 不会被调用
+}, function(e) {
+  console.log(e); // TypeError: Throwing
+});
+
+// Thenable在callback之后抛出异常
+// Promise resolves
+var thenable = { then: function(resolve) {
+  resolve("Resolving");
+  throw new TypeError("Throwing");
+}};
+
+var p3 = Promise.resolve(thenable);
+p3.then(function(v) {
+  console.log(v); // 输出"Resolving"
+}, function(e) {
+  // 不会被调用
+});
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-promise.resolve', 'Promise.resolve')}}{{Spec2('ES6')}}ECMA标准中的首次定义
{{SpecName('ESDraft', '#sec-promise.resolve', 'Promise.resolve')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Promise.resolve")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/then/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/then/index.html new file mode 100644 index 0000000000..c41a74f379 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/promise/then/index.html @@ -0,0 +1,304 @@ +--- +title: Promise.prototype.then() +slug: Web/JavaScript/Reference/Global_Objects/Promise/then +tags: + - ECMAScript 2015 + - JavaScript + - Promise + - Prototype + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/then +--- +
{{JSRef}}
+ +

then() 方法返回一个 {{domxref("Promise")}}。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。

+ +
{{EmbedInteractiveExample("pages/js/promise-then.html")}}
+ + + +
+

注意:如果忽略针对某个状态的回调函数参数,或者提供非函数 (nonfunction) 参数,那么 then 方法将会丢失关于该状态的回调函数信息,但是并不会产生错误。如果调用 thenPromise 的状态(fulfillment 或 rejection)发生改变,但是 then 中并没有关于这种状态的回调函数,那么 then 将创建一个没有经过回调函数处理的新 Promise 对象,这个新 Promise 只是简单地接受调用这个 then 的原 Promise 的终态作为它的终态。

+
+ +

语法

+ +
p.then(onFulfilled[, onRejected]);
+
+p.then(value => {
+  // fulfillment
+}, reason => {
+  // rejection
+});
+
+ +

参数

+ +
+
onFulfilled {{optional_inline}}
+
当 Promise 变成接受状态(fulfilled)时调用的{{jsxref("Function", "函数")}}。该函数有一个参数,即接受的最终结果(the fulfillment  value)。如果该参数不是函数,则会在内部被替换为 (x) => x,即原样返回 promise 最终结果的函数
+
onRejected {{optional_inline}}
+
当 Promise 变成拒绝状态(rejected)时调用的{{jsxref("Function", "函数")}}。该函数有一个参数,即拒绝的原因(rejection reason)。  如果该参数不是函数,则会在内部被替换为一个 "Thrower" 函数 (it throws an error it received as argument)。
+
+ +

返回值

+ +

当一个 {{jsxref("Promise")}} 完成(fulfilled)或者失败(rejected)时,返回函数将被异步调用(由当前的线程循环来调度完成)。具体的返回值依据以下规则返回。如果 then 中的回调函数:

+ + + +

下面是一个演示 then 方法的同步性的例子。

+ +
// using a resolved promise, the 'then' block will be triggered instantly,
+// but its handlers will be triggered asynchronously as demonstrated by the console.logs
+const resolvedProm = Promise.resolve(33);
+
+let thenProm = resolvedProm.then(value => {
+    console.log("this gets called after the end of the main stack. the value received and returned is: " + value);
+    return value;
+});
+// instantly logging the value of thenProm
+console.log(thenProm);
+
+// using setTimeout we can postpone the execution of a function to the moment the stack is empty
+setTimeout(() => {
+    console.log(thenProm);
+});
+
+
+// 上面的代码会依次返回:
+// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
+// "this gets called after the end of the main stack. the value received and returned is: 33"
+// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 33}
+ +

描述

+ +

由于 then 和 {{jsxref("Promise.prototype.catch()")}} 方法都会返回 promise,它们可以被链式调用——这同时也是一种被称为复合( composition) 的操作。

+ +

示例

+ +

使用 then 方法

+ +
var p1 = new Promise((resolve, reject) => {
+  resolve('成功!');
+  // or
+  // reject(new Error("出错了!"));
+});
+
+p1.then(value => {
+  console.log(value); // 成功!
+}, reason => {
+  console.error(reason); // 出错了!
+});
+
+ +

链式调用

+ +

then 方法返回一个 Promise 对象,其允许方法链。

+ +

你可以传递一个匿名函数给 then,并且,如果它返回一个 Promise,一个等价的 Promise 将暴露给后续的方法链。下面的代码片段使用 setTimout 函数来模拟异步代码操作。

+ +
Promise.resolve("foo")
+  // 1. 接收 "foo" 并与 "bar" 拼接,并将其结果做为下一个 resolve 返回。
+  .then(function(string) {
+    return new Promise(function(resolve, reject) {
+      setTimeout(function() {
+        string += 'bar';
+        resolve(string);
+      }, 1);
+    });
+  })
+  // 2. 接收 "foobar", 放入一个异步函数中处理该字符串
+  // 并将其打印到控制台中, 但是不将处理后的字符串返回到下一个。
+  .then(function(string) {
+    setTimeout(function() {
+      string += 'baz';
+      console.log(string);
+    }, 1)
+    return string;
+  })
+  // 3. 打印本节中代码将如何运行的帮助消息,
+  // 字符串实际上是由上一个回调函数之前的那块异步代码处理的。
+  .then(function(string) {
+    console.log("Last Then:  oops... didn't bother to instantiate and return " +
+                "a promise in the prior then so the sequence may be a bit " +
+                "surprising");
+
+    // 注意 `string` 这时不会存在 'baz'。
+    // 因为这是发生在我们通过setTimeout模拟的异步函数中。
+    console.log(string);
+  });
+
+// logs, in order:
+// Last Then: oops... didn't bother to instantiate and return a promise in the prior then so the sequence may be a bit surprising
+// foobar
+// foobarbaz
+ +

当一个值只是从一个 then 内部返回时,它将等价地返回 Promise.resolve(<由被调用的处理程序返回的值>)

+ +
var p2 = new Promise(function(resolve, reject) {
+  resolve(1);
+});
+
+p2.then(function(value) {
+  console.log(value); // 1
+  return value + 1;
+}).then(function(value) {
+  console.log(value + ' - A synchronous value works');
+});
+
+p2.then(function(value) {
+  console.log(value); // 1
+});
+
+ +

如果函数抛出错误或返回一个拒绝的Promise,则 then 将返回一个拒绝的Promise。

+ +
Promise.resolve()
+  .then(() => {
+    // 使 .then() 返回一个 rejected promise
+    throw new Error('Oh no!');
+  })
+  .then(() => {
+    console.log('Not called.');
+  }, error => {
+    console.error('onRejected function called: ' + error.message);
+  });
+ +

在其他情况下,一个 resolving Promise 会被返回。在下面的例子里,第一个 then() 会返回一个用 resolving Promise 包装的 42,即使之前的 Promise 是 rejected 的。

+ +
Promise.reject()
+  .then(() => 99, () => 42) // onRejected returns 42 which is wrapped in a resolving Promise
+  .then(solution => console.log('Resolved with ' + solution)); // Resolved with 42
+ +

实际上,捕获 rejected promise 的需求经常大于使用 then 的两种情况语法,比如下面这样的:

+ +
Promise.resolve()
+  .then(() => {
+    // 使 .then() 返回一个 rejected promise
+    throw new Error('Oh no!');
+  })
+  .catch(error => {
+    console.error('onRejected function called: ' + error.message);
+  })
+  .then(() => {
+    console.log("I am always called even if the prior then's promise rejects");
+  });
+ +

你也可以在另一个顶层函数上使用链式去实现基于 Promise API 的函数。

+ +
function fetch_current_data() {
+  // fetch() API 返回了一个 Promise.
+  // 这个函数提供了类似的API,
+  // 这个函数除了实现 Promise,它还能够完成更多的工作。
+  return fetch('current-data.json').then(response => {
+    if (response.headers.get('content-type') != 'application/json') {
+      throw new TypeError();
+    }
+    var j = response.json();
+    // maybe do something with j
+    return j; // fulfillment value given to user of
+              // fetch_current_data().then()
+  });
+}
+
+ +

如果 onFulfilled 返回了一个 promise,then 的返回值就会被 Promise resolved 或者 rejected。

+ +
function resolveLater(resolve, reject) {
+  setTimeout(function() {
+    resolve(10);
+  }, 1000);
+}
+function rejectLater(resolve, reject) {
+  setTimeout(function() {
+    reject(new Error('Error'));
+  }, 1000);
+}
+
+var p1 = Promise.resolve('foo');
+var p2 = p1.then(function() {
+  // Return promise here, that will be resolved to 10 after 1 second
+  return new Promise(resolveLater);
+});
+p2.then(function(v) {
+  console.log('resolved', v);  // "resolved", 10
+}, function(e) {
+  // not called
+  console.error('rejected', e);
+});
+
+var p3 = p1.then(function() {
+  // Return promise here, that will be rejected with 'Error' after 1 second
+  return new Promise(rejectLater);
+});
+p3.then(function(v) {
+  // not called
+  console.log('resolved', v);
+}, function(e) {
+  console.error('rejected', e); // "rejected", 'Error'
+});
+
+ +

基于 promise 的 {{domxref("window.setImmediate")}} polyfill

+ +

Using a {{jsxref("Function.prototype.bind()")}} Reflect.apply ({{jsxref("Reflect.apply()")}}) method to create a (non-cancellable) setImmediate-style function.

+ +
const nextTick = (() => {
+  const noop = () => {}; // literally
+  const nextTickPromise = () => Promise.resolve().then(noop);
+
+  const rfab = Reflect.apply.bind; // (thisArg, fn, thisArg, [...args])
+  const nextTick = (fn, ...args) => (
+    fn !== undefined
+    ? Promise.resolve(args).then(rfab(null, fn, null))
+    : nextTickPromise(),
+    undefined
+  );
+  nextTick.ntp = nextTickPromise;
+
+  return nextTick;
+})();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-promise.prototype.then', 'Promise.prototype.then')}}{{Spec2('ES2015')}}ECMA 标准中的首次定义。
{{SpecName('ESDraft', '#sec-promise.prototype.then', 'Promise.prototype.then')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Promise.then")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/apply/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/apply/index.html new file mode 100644 index 0000000000..62b8b67f5f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/apply/index.html @@ -0,0 +1,117 @@ +--- +title: handler.apply() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply +tags: + - ECMAScript6 + - JavaScript + - Method + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply +--- +
{{JSRef}}
+ +

handler.apply() 方法用于拦截函数的调用。

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-apply.html", "taller")}}
+ + + +

语法

+ +
var p = new Proxy(target, {
+  apply: function(target, thisArg, argumentsList) {
+  }
+});
+
+ +

参数

+ +

以下是传递给apply方法的参数,this上下文绑定在handler对象上.

+ +
+
target
+
目标对象(函数)。
+
thisArg
+
被调用时的上下文对象。
+
argumentsList
+
被调用时的参数数组。
+
+ +

返回值

+ +

apply方法可以返回任何值。

+ +

描述

+ +

handler.apply 方法用于拦截函数的调用。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作:

+ + + +

约束

+ +

如果违反了以下约束,代理将抛出一个TypeError:

+ +

target必须是可被调用的。也就是说,它必须是一个函数对象。

+ +

示例

+ +

以下代码演示如何捕获函数的调用。

+ +
var p = new Proxy(function() {}, {
+  apply: function(target, thisArg, argumentsList) {
+    console.log('called: ' + argumentsList.join(', '));
+    return argumentsList[0] + argumentsList[1] + argumentsList[2];
+  }
+});
+
+console.log(p(1, 2, 3)); // "called: 1, 2, 3"
+                         // 6
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.apply")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/construct/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/construct/index.html new file mode 100644 index 0000000000..209e9752e3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/construct/index.html @@ -0,0 +1,130 @@ +--- +title: handler.construct() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/construct +--- +
{{JSRef}}
+ +

handler.construct() 方法用于拦截{{jsxref("Operators/new", "new")}} 操作符. 为了使new操作符在生成的Proxy对象上生效,用于初始化代理的目标对象自身必须具有[[Construct]]内部方法(即 new target 必须是有效的)。

+ +

{{EmbedInteractiveExample("pages/js/proxyhandler-construct.html", "taller")}}

+ +

语法

+ +
var p = new Proxy(target, {
+  construct: function(target, argumentsList, newTarget) {
+  }
+});
+
+ +

参数

+ +

下面的参数将会传递给construct方法,this绑定在handler上。

+ +
+
target
+
目标对象。
+
argumentsList
+
constructor的参数列表。
+
newTarget
+
最初被调用的构造函数,就上面的例子而言是p。
+
+ +

返回值

+ +

construct 方法必须返回一个对象。

+ +

描述

+ +

handler.construct() 方法用于拦截 {{jsxref("Operators/new", "new")}}操作符。

+ +

拦截

+ +

该拦截器可以拦截以下操作:

+ + + +

约束

+ +

如果违反以下约定,代理将会抛出错误 {{jsxref("TypeError")}}:

+ + + +

示例

+ +

下面代码演示如何拦截 {{jsxref("Operators/new", "new")}} 操作。

+ +
var p = new Proxy(function() {}, {
+  construct: function(target, argumentsList, newTarget) {
+    console.log('called: ' + argumentsList.join(', '));
+    return { value: argumentsList[0] * 10 };
+  }
+});
+
+console.log(new p(1).value); // "called: 1"
+                             // 10
+
+ +

下面的代码违反了约定.

+ +
var p = new Proxy(function() {}, {
+  construct: function(target, argumentsList, newTarget) {
+    return 1;
+  }
+});
+
+new p(); // TypeError is thrown
+
+ +

下面的代码未能正确的初始化Proxy。Proxy初始化时,传给它的target 必须具有一个有效的constructor供new操作符调用。

+ +
var p = new Proxy({}, {
+  construct: function(target, argumentsList, newTarget) {
+    return {};
+  }
+});
+
+new p(); // TypeError is thrown, "p" is not a constructor
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget', '[[Construct]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget', '[[Construct]]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{Compat("javascript.builtins.Proxy.handler.construct")}}
+ +
 
+ +

相关主题

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/defineproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/defineproperty/index.html new file mode 100644 index 0000000000..9912e043a0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/defineproperty/index.html @@ -0,0 +1,181 @@ +--- +title: handler.defineProperty() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/defineProperty +--- +
{{JSRef}}
+ +

handler.defineProperty() 用于拦截对对象的 {{jsxref("Object.defineProperty()")}} 操作。

+ +

语法

+ +
var p = new Proxy(target, {
+  defineProperty: function(target, property, descriptor) {
+  }
+});
+
+ +

参数

+ +

下列参数将会被传递给 defineProperty 方法。 this 绑定在 handler 对象上。

+ +
+
target
+
目标对象。
+
property
+
待检索其描述的属性名。
+
descriptor
+
待定义或修改的属性的描述符。
+
+ +

返回值

+ +

defineProperty 方法必须以一个 {{jsxref("Boolean")}} 返回,表示定义该属性的操作成功与否。

+ +

描述

+ +

handler.defineProperty() 用于拦截对对象的 {{jsxref("Object.defineProperty()")}} 操作。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作 :

+ + + +

不变量

+ +

如果违背了以下的不变量,proxy会抛出 {{jsxref("TypeError")}}:

+ + + +

示例

+ +

以下代码演示如何拦截对目标对象的 {{jsxref("Object.defineProperty()")}} 操作。

+ +
var p = new Proxy({}, {
+  defineProperty: function(target, prop, descriptor) {
+    console.log('called: ' + prop);
+    return true;
+  }
+});
+
+var desc = { configurable: true, enumerable: true, value: 10 };
+Object.defineProperty(p, 'a', desc); // "called: a"
+
+ +

当调用 {{jsxref("Object.defineProperty()")}} 或者 {{jsxref("Reflect.defineProperty()")}},传递给 definePropertydescriptor   有一个限制 - 只有以下属性才有用,非标准的属性将会被无视 :

+ + + +
var p = new Proxy({}, {
+  defineProperty(target, prop, descriptor) {
+    console.log(descriptor);
+    return Reflect.defineProperty(target, prop, descriptor);
+  }
+});
+
+Object.defineProperty(p, 'name', {
+  value: 'proxy',
+  type: 'custom'
+});  // { value: 'proxy' }
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc', '[[DefineOwnProperty]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc', '[[DefineOwnProperty]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html new file mode 100644 index 0000000000..6cb4255755 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html @@ -0,0 +1,149 @@ +--- +title: handler.deleteProperty() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/deleteProperty +--- +
{{JSRef}}
+ +

handler.deleteProperty() 方法用于拦截对对象属性的 {{jsxref("Operators/delete", "delete")}} 操作。

+ +

语法

+ +
var p = new Proxy(target, {
+  deleteProperty: function(target, property) {
+  }
+});
+
+ +

参数

+ +

deleteProperty 方法将会接受以下参数。 this 被绑定在 handler上。

+ +
+
target
+
目标对象。
+
property
+
待删除的属性名。
+
+ +

返回值

+ +

deleteProperty 必须返回一个 {{jsxref("Boolean")}} 类型的值,表示了该属性是否被成功删除。

+ +

描述

+ +

handler.deleteProperty() 方法可以拦截 {{jsxref("Operators/delete", "delete")}} 操作。

+ +

拦截

+ +

该方法会拦截以下操作:

+ + + +

不变量

+ +

如果违背了以下不变量,proxy 将会抛出一个 {{jsxref("TypeError")}}:

+ + + +

示例

+ +

以下代码演示了对 {{jsxref("Operators/delete", "delete")}} 操作的拦截。

+ +
var p = new Proxy({}, {
+  deleteProperty: function(target, prop) {
+    console.log('called: ' + prop);
+    return true;
+  }
+});
+
+delete p.a; // "called: a"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/get/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/get/index.html new file mode 100644 index 0000000000..14a350436a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/get/index.html @@ -0,0 +1,177 @@ +--- +title: handler.get() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/get +tags: + - ECMAScript6 + - JavaScript + - Method + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get +--- +
{{JSRef}}
+ +

handler.get() 方法用于拦截对象的读取属性操作。

+ +

语法

+ +
var p = new Proxy(target, {
+  get: function(target, property, receiver) {
+  }
+});
+
+ +

参数

+ +

以下是传递给get方法的参数,this上下文绑定在handler对象上.

+ +
+
target
+
目标对象。
+
property
+
被获取的属性名。
+
receiver
+
Proxy或者继承Proxy的对象
+
+ +

返回值

+ +

get方法可以返回任何值。

+ +

描述

+ +

handler.get 方法用于拦截对象的读取属性操作。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作:

+ + + +

约束

+ +

如果违背了以下的约束,proxy会抛出 {{jsxref("TypeError")}}:

+ + + +

示例

+ +

以下代码演示如何拦截属性值的读取操作。

+ +
var p = new Proxy({}, {
+  get: function(target, prop, receiver) {
+    console.log("called: " + prop);
+    return 10;
+  }
+});
+
+console.log(p.a); // "called: a"
+                  // 10
+
+ +

以下代码演示违反约束的情况。

+ +
var obj = {};
+Object.defineProperty(obj, "a", {
+  configurable: false,
+  enumerable: false,
+  value: 10,
+  writable: false
+});
+
+var p = new Proxy(obj, {
+  get: function(target, prop) {
+    return 20;
+  }
+});
+
+p.a; //会抛出TypeError
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver', '[[Get]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver', '[[Get]]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getownpropertydescriptor/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getownpropertydescriptor/index.html new file mode 100644 index 0000000000..470b2c6ad9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getownpropertydescriptor/index.html @@ -0,0 +1,168 @@ +--- +title: handler.getOwnPropertyDescriptor() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor +--- +
{{JSRef}}
+ +

handler.getOwnPropertyDescriptor() 方法是 {{jsxref("Object.getOwnPropertyDescriptor()")}}  的钩子。

+ +

语法

+ +
var p = new Proxy(target, {
+  getOwnPropertyDescriptor: function(target, prop) {
+  }
+});
+
+ +

参数

+ +

下列参数会被传入 getOwnPropertyDescriptor 方法中。这是绑定到handler上。 

+ +
+
target
+
目标对象。
+
prop
+
返回属性名称的描述。
+
+ +

返回值

+ +

getOwnPropertyDescriptor 方法必须返回一个 object 或 undefined

+ +

描述

+ +

handler.getOwnPropertyDescriptor() 方法是 {{jsxref("Object.getOwnPropertyDescriptor()")}} 的陷阱。

+ +

拦截

+ +

这个陷阱可以拦截这些操作:

+ + + +

不变量

+ +

如果下列不变量被违反,代理将抛出一个 {{jsxref("TypeError")}}:

+ + + +

示例

+ +

以下是 {{jsxref("Object.getOwnPropertyDescriptor()")}} 的代码陷阱:

+ +
var p = new Proxy({ a: 20}, {
+  getOwnPropertyDescriptor: function(target, prop) {
+    console.log('called: ' + prop);
+    return { configurable: true, enumerable: true, value: 10 };
+  }
+});
+
+console.log(Object.getOwnPropertyDescriptor(p, 'a').value); // "called: a"
+                                                            // 10
+
+ +

以下代码则违反了不变量。

+ +
var obj = { a: 10 };
+Object.preventExtensions(obj);
+var p = new Proxy(obj, {
+  getOwnPropertyDescriptor: function(target, prop) {
+    return undefined;
+  }
+});
+
+Object.getOwnPropertyDescriptor(p, 'a'); // TypeError is thrown
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p', '[[GetOwnProperty]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p', '[[GetOwnProperty]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getprototypeof/index.html new file mode 100644 index 0000000000..215d2d9646 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getprototypeof/index.html @@ -0,0 +1,141 @@ +--- +title: handler.getPrototypeOf() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Proxy + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getPrototypeOf +--- +
{{JSRef("Global_Objects", "Proxy")}}
+ +

handler.getPrototypeOf() 是一个代理(Proxy)方法,当读取代理对象的原型时,该方法就会被调用。

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-getprototypeof.html", "taller")}}
+ + + +

语法

+ +
const p = new Proxy(obj, {
+  getPrototypeOf(target) {
+  ...
+  }
+});
+
+ +

参数

+ +

getPrototypeOf 方法被调用时,this 指向的是它所属的处理器对象。

+ +
+
target
+
被代理的目标对象。
+
+ +

返回值

+ +

getPrototypeOf 方法的返回值必须是一个对象或者 null

+ +

描述

+ +

在 JavaScript 中,下面这五种操作(方法/属性/运算符)可以触发 JS 引擎读取一个对象的原型,也就是可以触发 getPrototypeOf() 代理方法的运行:

+ + + +

如果遇到了下面两种情况,JS 引擎会抛出 {{jsxref("TypeError")}} 异常:

+ + + +

示例

+ +

基本用法

+ +
var obj = {};
+var proto = {};
+var handler = {
+    getPrototypeOf(target) {
+        console.log(target === obj);   // true
+        console.log(this === handler); // true
+        return proto;
+    }
+};
+
+var p = new Proxy(obj, handler);
+console.log(Object.getPrototypeOf(p) === proto);    // true
+
+ +

5 种触发 getPrototypeOf 代理方法的方式

+ +
var obj = {};
+var p = new Proxy(obj, {
+    getPrototypeOf(target) {
+        return Array.prototype;
+    }
+});
+console.log(
+    Object.getPrototypeOf(p) === Array.prototype,  // true
+    Reflect.getPrototypeOf(p) === Array.prototype, // true
+    p.__proto__ === Array.prototype,               // true
+    Array.prototype.isPrototypeOf(p),              // true
+    p instanceof Array                             // true
+);
+
+ +

两种情况下的异常

+ +
var obj = {};
+var p = new Proxy(obj, {
+    getPrototypeOf(target) {
+        return "foo";
+    }
+});
+Object.getPrototypeOf(p); // TypeError: "foo" is not an object or null
+
+var obj = Object.preventExtensions({});
+var p = new Proxy(obj, {
+    getPrototypeOf(target) {
+        return {};
+    }
+});
+Object.getPrototypeOf(p); // TypeError: expected same prototype value
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof', '[[GetPrototypeOf]]')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Proxy.handler.getPrototypeOf")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/has/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/has/index.html new file mode 100644 index 0000000000..fead0846ff --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/has/index.html @@ -0,0 +1,176 @@ +--- +title: handler.has() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/has +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/has +--- +
{{JSRef}}
+ +

 handler.has() 方法是针对 {{jsxref("Operators/in", "in")}} 操作符的代理方法。

+ + + + + +

{{EmbedInteractiveExample("pages/js/proxyhandler-has.html", "taller")}}

+ + + + + +

语法

+ +
var p = new Proxy(target, {
+  has: function(target, prop) {
+  }
+});
+
+ +

参数

+ +

下面是传递给 has 方法的参数. this is bound to the handler.

+ +
+
target
+
目标对象.
+
prop
+
需要检查是否存在的属性.
+
+ +

返回值

+ +

has 方法返回一个 boolean 属性的值.

+ +

描述

+ +

handler.has 方法可以看作是针对 {{jsxref("Operators/in", "in")}} 操作的钩子.

+ +

拦截

+ +

这个钩子可以拦截下面这些操作:

+ + + +

约束

+ +

如果违反了下面这些规则,  proxy 将会抛出 {{jsxref("TypeError")}}:

+ + + +

示例

+ +

下面的代码拦截了 {{jsxref("Operators/in", "in")}} 操作符.

+ +
var p = new Proxy({}, {
+  has: function(target, prop) {
+    console.log('called: ' + prop);
+    return true;
+  }
+});
+
+console.log('a' in p); // "called: a"
+                       // true
+
+ +

下面的代码违反了约束.

+ +
var obj = { a: 10 };
+Object.preventExtensions(obj);
+var p = new Proxy(obj, {
+  has: function(target, prop) {
+    return false;
+  }
+});
+
+'a' in p; // TypeError is thrown
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p', '[[HasProperty]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p', '[[HasProperty]]')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

其他

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/index.html new file mode 100644 index 0000000000..7cbefe2838 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/index.html @@ -0,0 +1,76 @@ +--- +title: Proxy handler +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler +tags: + - ECMAScript 2015 + - JavaScript + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +--- +
{{JSRef}}
+ +
Proxy 的 handler 对象是一个占位符对象,它包含了用于 {{jsxref("Proxy")}} 的陷阱(Trap)函数。
+ +
此处可以理解为由Proxy所暴露出的钩子函数,handler作为挂载钩子函数的对象存在,不同的操作会触发不同的钩子函数
+ +
,handler提供了覆写钩子函数的方法。
+ +

方法

+ +

所有的陷阱是可选的。如果某个陷阱没有定义,那么就会保留默认行为。

+ +
+
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
+
在读取代理对象的原型时触发该操作,比如在执行 {{jsxref("Object.getPrototypeOf")}}(proxy) 时。
+
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
+
在设置代理对象的原型时触发该操作,比如在执行 {{jsxref("Object.setPrototypeOf")}}(proxy, null) 时。
+
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
+
在判断一个代理对象是否是可扩展时触发该操作,比如在执行 {{jsxref("Object.isExtensible")}}(proxy) 时。
+
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
+
在让一个代理对象不可扩展时触发该操作,比如在执行 {{jsxref("Object.preventExtensions")}}(proxy) 时。
+
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
+
在获取代理对象某个属性的属性描述时触发该操作,比如在执行 {{jsxref("Object.getOwnPropertyDescriptor")}}(proxy, "foo") 时。
+
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
+
在定义代理对象某个属性时的属性描述时触发该操作,比如在执行 {{jsxref("Object.defineProperty")}}(proxy, "foo", {}) 时。
+
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}
+
在判断代理对象是否拥有某个属性时触发该操作,比如在执行 "foo" {{jsxref("Operators/in", "in")}} proxy 时。
+
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}
+
在读取代理对象的某个属性时触发该操作,比如在执行 proxy.foo 时。
+
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}
+
在给代理对象的某个属性赋值时触发该操作,比如在执行 proxy.foo = 1 时。
+
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
+
在删除代理对象的某个属性时触发该操作,即使用 {{jsxref("Operators/delete", "delete")}} 运算符,比如在执行 delete proxy.foo 时。
+
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}
+
{{jsxref("Object.getOwnPropertyNames")}} 和{{jsxref("Object.getOwnPropertySymbols")}} 的陷阱。
+
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}
+
函数调用操作的陷阱。
+
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}
+
{{jsxref("Operators/new", "new")}} 运算符的陷阱。
+
+ +

一些不标准的陷阱已经废弃并且被移除了

+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Proxy.handler")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/isextensible/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/isextensible/index.html new file mode 100644 index 0000000000..7be418197f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/isextensible/index.html @@ -0,0 +1,123 @@ +--- +title: handler.isExtensible() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/isExtensible +--- +
{{JSRef}}
+handler.isExtensible() 方法用于拦截对对象的Object.isExtensible()。
+ +
+

{{EmbedInteractiveExample("pages/js/proxyhandler-isextensible.html", "taller")}}

+
+ +

语法

+ +
var p = new Proxy(target, {
+  isExtensible: function(target) {
+  }
+});
+
+ +

参数

+ +

下列参数将会被传递给 isExtensible方法。 this 绑定在 handler 对象上。

+ +
+
target
+
目标对象。
+
+ +

返回值

+ +

isExtensible方法必须返回一个 Boolean值或可转换成Boolean的值。

+ +

描述

+ +

handler.isExtensible()用于拦截对对象的Object.isExtensible()。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作:

+ + + +

约束

+ +

如果违背了以下的约束,proxy会抛出 TypeError:

+ + + +

示例

+ +

以下代码演示{{jsxref("Object.isExtensible()")}}.

+ +
var p = new Proxy({}, {
+  isExtensible: function(target) {
+    console.log('called');
+    return true;//也可以return 1;等表示为true的值
+  }
+});
+
+console.log(Object.isExtensible(p)); // "called"
+                                     // true
+
+ +

以下代码演示违反约束的情况。

+ +
var p = new Proxy({}, {
+  isExtensible: function(target) {
+    return false;//return 0;return NaN等都会报错
+  }
+});
+
+Object.isExtensible(p); // TypeError is thrown
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-isextensible', '[[IsExtensible]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-isextensible', '[[IsExtensible]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.isExtensible")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/ownkeys/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/ownkeys/index.html new file mode 100644 index 0000000000..956b908375 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/ownkeys/index.html @@ -0,0 +1,193 @@ +--- +title: handler.ownKeys() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/ownKeys +--- +
{{JSRef}}
+ +

handler.ownKeys() 方法用于拦截 {{jsxref("Reflect.ownKeys()")}}.

+ + + +

{{EmbedInteractiveExample("pages/js/proxyhandler-ownkeys.html", "taller")}}

+ + + +

语法

+ +
var p = new Proxy(target, {
+  ownKeys: function(target) {
+  }
+});
+
+ +

参数

+ +

下面的参数被传递给ownKeys。this被绑定在handler上。

+ +
+
target
+
目标对象.
+
+ +

返回值

+ +

ownKeys 方法必须返回一个可枚举对象.

+ +

描述

+ +

handler.ownKeys() 方法用于拦截 {{jsxref("Reflect.ownKeys()")}}.

+ +

拦截

+ +

该拦截器可以拦截以下操作::

+ + + +

约束

+ +

如果违反了下面的约束,proxy将抛出错误 {{jsxref("TypeError")}}:

+ + + +

示例

+ +

下面的代码拦截 {{jsxref("Object.getOwnPropertyNames()")}}.

+ +
var p = new Proxy({}, {
+  ownKeys: function(target) {
+    console.log('called');
+    return ['a', 'b', 'c'];
+  }
+});
+
+console.log(Object.getOwnPropertyNames(p)); // "called"
+                                            // [ 'a', 'b', 'c' ]
+ +

下面的代码违反了约定

+ +
var obj = {};
+Object.defineProperty(obj, 'a', {
+  configurable: false,
+  enumerable: true,
+  value: 10 }
+);
+
+var p = new Proxy(obj, {
+  ownKeys: function(target) {
+    return [123, 12.5, true, false, undefined, null, {}, []];
+  }
+});
+
+console.log(Object.getOwnPropertyNames(p));
+
+// TypeError: proxy [[OwnPropertyKeys]] 必须返回一个数组
+// 数组元素类型只能是String或Symbol
+
+ +

标准

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys', '[[OwnPropertyKeys]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys', '[[OwnPropertyKeys]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

兼容性注意事项

+ +

Firefox火狐

+ + + +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/preventextensions/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/preventextensions/index.html new file mode 100644 index 0000000000..dd6823c9dd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/preventextensions/index.html @@ -0,0 +1,120 @@ +--- +title: handler.preventExtensions() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions +tags: + - Proxy 代理 拦截 +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/preventExtensions +--- +
{{JSRef}}
+ +

handler.preventExtensions() 方法用于设置对{{jsxref("Object.preventExtensions()")}}的拦截

+ +

{{EmbedInteractiveExample("pages/js/proxyhandler-preventextensions.html", "taller")}}

+ +

语法

+ +
var p = new Proxy(target, {
+  preventExtensions: function(target) {
+  }
+});
+
+ +

参数

+ +

以下参数传递给 preventExtensions 方法. 它会绑定到这个handler.

+ +
+
target
+
所要拦截的目标对象.
+
+ +

返回值

+ +

preventExtensions 方法返回一个布尔值.

+ +

描述

+ +

handler.preventExtensions() 拦截 {{jsxref("Object.preventExtensions()")}}返回一个布尔值.

+ +

拦截

+ +

这个trap可以拦截这些操作:

+ + + +

约束

+ +

如果违反了下列规则, proxy则会抛出一个 {{jsxref("TypeError")}}:

+ + + +

示例

+ +

以下代码演示了如何拦截{{jsxref("Object.preventExtensions()")}}。

+ +
var p = new Proxy({}, {
+  preventExtensions: function(target) {
+    console.log('called');
+    Object.preventExtensions(target);
+    return true;
+  }
+});
+
+console.log(Object.preventExtensions(p)); // "called"
+                                          // false
+
+ +

以下代码违反了约束.

+ +
var p = new Proxy({}, {
+  preventExtensions: function(target) {
+    return true;
+  }
+});
+
+Object.preventExtensions(p); // 抛出类型错误
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-preventextensions', '[[PreventExtensions]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-preventextensions', '[[PreventExtensions]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.preventExtensions")}}

+
+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/set/index.html new file mode 100644 index 0000000000..c66481647a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/set/index.html @@ -0,0 +1,125 @@ +--- +title: handler.set() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/set +tags: + - ECMAScript6 + - JavaScript + - Method + - Proxy + - Proxy拦截 +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/set +--- +
{{JSRef}}
+ +

handler.set() 方法是设置属性值操作的捕获器。

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-set.html", "taller")}}
+ + + +

语法

+ +
const p = new Proxy(target, {
+  set: function(target, property, value, receiver) {
+  }
+});
+
+ +

参数

+ +

以下是传递给 set() 方法的参数。this 绑定在 handler 对象上。

+ +
+
target
+
目标对象。
+
property
+
将被设置的属性名或 {{jsxref("Symbol")}}。
+
value
+
新属性值。
+
receiver
+
最初被调用的对象。通常是 proxy 本身,但 handler 的 set 方法也有可能在原型链上,或以其他方式被间接地调用(因此不一定是 proxy 本身)。 +
+

比如:假设有一段代码执行 obj.name = "jen"obj 不是一个 proxy,且自身不含 name 属性,但是它的原型链上有一个 proxy,那么,那个 proxy 的 set() 处理器会被调用,而此时,obj 会作为 receiver 参数传进来。

+
+
+
+ +

返回值

+ +

set() 方法应当返回一个布尔值。

+ + + +

描述

+ +

handler.set() 方法用于拦截设置属性值的操作。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作:

+ + + +

约束

+ +

如果违背以下的约束条件,proxy 会抛出一个 {{jsxref("TypeError")}} 异常:

+ + + +

示例

+ +

以下代码演示如何捕获属性的设置操作。

+ +
var p = new Proxy({}, {
+  set: function(target, prop, value, receiver) {
+    target[prop] = value;
+    console.log('property set: ' + prop + ' = ' + value);
+    return true;
+  }
+})
+
+console.log('a' in p);  // false
+
+p.a = 10;               // "property set: a = 10"
+console.log('a' in p);  // true
+console.log(p.a);       // 10
+ +

规范

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver', '[[Set]]')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Proxy.handler.set")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/setprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/setprototypeof/index.html new file mode 100644 index 0000000000..9d88cd2593 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/setprototypeof/index.html @@ -0,0 +1,124 @@ +--- +title: handler.setPrototypeOf() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/setPrototypeOf +--- +
{{JSRef}}
+ +

handler.setPrototypeOf() 方法主要用来拦截 {{jsxref("Object.setPrototypeOf()")}}.

+ +

语法

+ +
var p = new Proxy(target, {
+  setPrototypeOf: function(target, prototype) {
+  }
+});
+
+ +

参数

+ +

以下参数传递给 setPrototypeOf 方法. 

+ +
+
target
+
被拦截目标对象.
+
prototype
+
对象新原型或为null.
+
+ +

返回值

+ +

如果成功修改了[[Prototype]]setPrototypeOf 方法返回 true,否则返回 false.

+ +

描述

+ +

这个 handler.setPrototypeOf 方法用于拦截 {{jsxref("Object.setPrototypeOf()")}}.

+ +

拦截

+ +

这个方法可以拦截以下操作:

+ + + +

Invariants

+ +

如果违反了下列规则,则proxy将抛出一个{{jsxref("TypeError")}}:

+ + + +

示例

+ +

如果你不想为你的对象设置一个新的原型,你的handler's的setPrototypeOf方法可以返回false,也可以抛出异常。

+ +

The former approach means that any operation that performs such mutation, that throws an exception on failure to mutate, will have to create the exception itself.  For example, {{jsxref("Object.setPrototypeOf()")}} will create and throw a TypeError itself.  If the mutation is performed by an operation that doesn't ordinarily throw in case of failure, such as {{jsxref("Reflect.setPrototypeOf()")}}, no exception will be thrown.

+ +
var handlerReturnsFalse = {
+    setPrototypeOf(target, newProto) {
+        return false;
+    }
+};
+
+var newProto = {}, target = {};
+
+var p1 = new Proxy(target, handlerReturnsFalse);
+Object.setPrototypeOf(p1, newProto); // throws a TypeError
+Reflect.setPrototypeOf(p1, newProto); // returns false
+
+ +

The latter approach will cause any operation that attempts to mutate, to throw.  This approach is required if you want even non-throwing operations to throw on failure, or you want to throw a custom exception value.

+ +
var handlerThrows = {
+    setPrototypeOf(target, newProto) {
+        throw new Error('custom error');
+    }
+};
+
+var newProto = {}, target = {};
+
+var p2 = new Proxy(target, handlerThrows);
+Object.setPrototypeOf(p2, newProto); // throws new Error("custom error")
+Reflect.setPrototypeOf(p2, newProto); // throws new Error("custom error")
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v', '[[SetPrototypeOf]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v', '[[SetPrototypeOf]]')}}{{Spec2('ESDraft')}} 
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.setPrototypeOf")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/index.html new file mode 100644 index 0000000000..f9059ade82 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/index.html @@ -0,0 +1,435 @@ +--- +title: Proxy +slug: Web/JavaScript/Reference/Global_Objects/Proxy +tags: + - ECMAScript 2015 + - JavaScript + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy +--- +
{{JSRef}}
+ +

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

+ +

术语

+ +
+
{{jsxref("Global_Objects/Proxy/handler", "handler")}}
+
包含捕捉器(trap)的占位符对象,可译为处理器对象。
+
traps
+
提供属性访问的方法。这类似于操作系统中捕获器的概念。
+
target
+
被 Proxy 代理虚拟化的对象。它常被作为代理的存储后端。根据目标验证关于对象不可扩展性或不可配置属性的不变量(保持不变的语义)。
+
+ +

语法

+ +
const p = new Proxy(target, handler)
+ +

参数

+ +
+
target
+
要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
+
handler
+
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
+
+ +

方法

+ +
+
{{jsxref("Proxy.revocable()")}}
+
创建一个可撤销的Proxy对象。
+
+ +

handler 对象的方法

+ +

handler 对象是一个容纳一批特定属性的占位符对象。它包含有 Proxy 的各个捕获器(trap)。

+ +

所有的捕捉器是可选的。如果没有定义某个捕捉器,那么就会保留源对象的默认行为。

+ +
+
{{JSxRef("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
+
{{JSxRef("Object.getPrototypeOf")}} 方法的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
+
{{JSxRef("Object.setPrototypeOf")}} 方法的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
+
{{JSxRef("Object.isExtensible")}} 方法的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
+
{{JSxRef("Object.preventExtensions")}} 方法的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
+
{{JSxRef("Object.getOwnPropertyDescriptor")}} 方法的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
+
{{JSxRef("Object.defineProperty")}} 方法的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/has", "handler.has()")}}
+
{{JSxRef("Operators/in", "in")}} 操作符的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/get", "handler.get()")}}
+
属性读取操作的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/set", "handler.set()")}}
+
属性设置操作的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
+
{{JSxRef("Operators/delete", "delete")}} 操作符的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}
+
{{JSxRef("Object.getOwnPropertyNames")}} 方法和 {{JSxRef("Object.getOwnPropertySymbols")}} 方法的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/apply", "handler.apply()")}}
+
函数调用操作的捕捉器。
+
{{JSxRef("Global_Objects/Proxy/handler/construct", "handler.construct()")}}
+
{{JSxRef("Operators/new", "new")}} 操作符的捕捉器。
+
+ +

一些不标准的捕捉器已经被废弃并且移除了。

+ +

示例

+ +

基础示例

+ +

在以下简单的例子中,当对象中不存在属性名时,默认返回值为 37。下面的代码以此展示了 {{jsxref("Global_Objects/Proxy/handler/get", "get")}} handler 的使用场景。

+ +
const handler = {
+    get: function(obj, prop) {
+        return prop in obj ? obj[prop] : 37;
+    }
+};
+
+const p = new Proxy({}, handler);
+p.a = 1;
+p.b = undefined;
+
+console.log(p.a, p.b);      // 1, undefined
+console.log('c' in p, p.c); // false, 37
+
+ +

无操作转发代理

+ +

在以下例子中,我们使用了一个原生 JavaScript 对象,代理会将所有应用到它的操作转发到这个对象上。

+ +
let target = {};
+let p = new Proxy(target, {});
+
+p.a = 37;   // 操作转发到目标
+
+console.log(target.a);    // 37. 操作已经被正确地转发
+
+ +

验证

+ +

通过代理,你可以轻松地验证向一个对象的传值。下面的代码借此展示了 {{jsxref("Global_Objects/Proxy/handler/set", "set")}} handler 的作用。

+ +
let validator = {
+  set: function(obj, prop, value) {
+    if (prop === 'age') {
+      if (!Number.isInteger(value)) {
+        throw new TypeError('The age is not an integer');
+      }
+      if (value > 200) {
+        throw new RangeError('The age seems invalid');
+      }
+    }
+
+    // The default behavior to store the value
+    obj[prop] = value;
+
+    // 表示成功
+    return true;
+  }
+};
+
+let person = new Proxy({}, validator);
+
+person.age = 100;
+
+console.log(person.age);
+// 100
+
+person.age = 'young';
+// 抛出异常: Uncaught TypeError: The age is not an integer
+
+person.age = 300;
+// 抛出异常: Uncaught RangeError: The age seems invalid
+
+ +

扩展构造函数

+ +

方法代理可以轻松地通过一个新构造函数来扩展一个已有的构造函数。这个例子使用了constructapply

+ +
function extend(sup, base) {
+  var descriptor = Object.getOwnPropertyDescriptor(
+    base.prototype, "constructor"
+  );
+  base.prototype = Object.create(sup.prototype);
+  var handler = {
+    construct: function(target, args) {
+      var obj = Object.create(base.prototype);
+      this.apply(target, obj, args);
+      return obj;
+    },
+    apply: function(target, that, args) {
+      sup.apply(that, args);
+      base.apply(that, args);
+    }
+  };
+  var proxy = new Proxy(base, handler);
+  descriptor.value = proxy;
+  Object.defineProperty(base.prototype, "constructor", descriptor);
+  return proxy;
+}
+
+var Person = function (name) {
+  this.name = name
+};
+
+var Boy = extend(Person, function (name, age) {
+  this.age = age;
+});
+
+Boy.prototype.sex = "M";
+
+var Peter = new Boy("Peter", 13);
+console.log(Peter.sex);  // "M"
+console.log(Peter.name); // "Peter"
+console.log(Peter.age);  // 13
+ +

操作 DOM 节点

+ +

有时,我们可能需要互换两个不同的元素的属性或类名。下面的代码以此为目标,展示了 {{jsxref("Global_Objects/Proxy/handler/set", "set")}} handler 的使用场景。

+ +
let view = new Proxy({
+  selected: null
+}, {
+  set: function(obj, prop, newval) {
+    let oldval = obj[prop];
+
+    if (prop === 'selected') {
+      if (oldval) {
+        oldval.setAttribute('aria-selected', 'false');
+      }
+      if (newval) {
+        newval.setAttribute('aria-selected', 'true');
+      }
+    }
+
+    // 默认行为是存储被传入 setter 函数的属性值
+    obj[prop] = newval;
+
+    // 表示操作成功
+    return true;
+  }
+});
+
+let i1 = view.selected = document.getElementById('item-1');
+console.log(i1.getAttribute('aria-selected')); // 'true'
+
+let i2 = view.selected = document.getElementById('item-2');
+console.log(i1.getAttribute('aria-selected')); // 'false'
+console.log(i2.getAttribute('aria-selected')); // 'true'
+
+ +

值修正及附加属性

+ +

以下products代理会计算传值并根据需要转换为数组。这个代理对象同时支持一个叫做 latestBrowser的附加属性,这个属性可以同时作为 getter 和 setter。

+ +
let products = new Proxy({
+  browsers: ['Internet Explorer', 'Netscape']
+}, {
+  get: function(obj, prop) {
+    // 附加一个属性
+    if (prop === 'latestBrowser') {
+      return obj.browsers[obj.browsers.length - 1];
+    }
+
+    // 默认行为是返回属性值
+    return obj[prop];
+  },
+  set: function(obj, prop, value) {
+    // 附加属性
+    if (prop === 'latestBrowser') {
+      obj.browsers.push(value);
+      return;
+    }
+
+    // 如果不是数组,则进行转换
+    if (typeof value === 'string') {
+      value = [value];
+    }
+
+    // 默认行为是保存属性值
+    obj[prop] = value;
+
+    // 表示成功
+    return true;
+  }
+});
+
+console.log(products.browsers); // ['Internet Explorer', 'Netscape']
+products.browsers = 'Firefox';  // 如果不小心传入了一个字符串
+console.log(products.browsers); // ['Firefox'] <- 也没问题, 得到的依旧是一个数组
+
+products.latestBrowser = 'Chrome';
+console.log(products.browsers);      // ['Firefox', 'Chrome']
+console.log(products.latestBrowser); // 'Chrome'
+
+ +

通过属性查找数组中的特定对象

+ +

以下代理为数组扩展了一些实用工具。如你所见,通过 Proxy,我们可以灵活地“定义”属性,而不需要使用 {{jsxref("Object.defineProperties")}} 方法。以下例子可以用于通过单元格来查找表格中的一行。在这种情况下,target 是 table.rows

+ +
let products = new Proxy([
+  { name: 'Firefox'    , type: 'browser' },
+  { name: 'SeaMonkey'  , type: 'browser' },
+  { name: 'Thunderbird', type: 'mailer' }
+], {
+  get: function(obj, prop) {
+    // 默认行为是返回属性值, prop ?通常是一个整数
+    if (prop in obj) {
+      return obj[prop];
+    }
+
+    // 获取 products 的 number; 它是 products.length 的别名
+    if (prop === 'number') {
+      return obj.length;
+    }
+
+    let result, types = {};
+
+    for (let product of obj) {
+      if (product.name === prop) {
+        result = product;
+      }
+      if (types[product.type]) {
+        types[product.type].push(product);
+      } else {
+        types[product.type] = [product];
+      }
+    }
+
+    // 通过 name 获取 product
+    if (result) {
+      return result;
+    }
+
+    // 通过 type 获取 products
+    if (prop in types) {
+      return types[prop];
+    }
+
+    // 获取 product type
+    if (prop === 'types') {
+      return Object.keys(types);
+    }
+
+    return undefined;
+  }
+});
+
+console.log(products[0]); // { name: 'Firefox', type: 'browser' }
+console.log(products['Firefox']); // { name: 'Firefox', type: 'browser' }
+console.log(products['Chrome']); // undefined
+console.log(products.browser); // [{ name: 'Firefox', type: 'browser' }, { name: 'SeaMonkey', type: 'browser' }]
+console.log(products.types); // ['browser', 'mailer']
+console.log(products.number); // 3
+
+ +

一个完整的 traps 列表示例

+ +

出于教学目的,这里为了创建一个完整的 traps 列表示例,我们将尝试代理化一个非原生对象,这特别适用于这类操作:由 发布在 document.cookie页面上的“小型框架”创建的docCookies全局对象。

+ +
/*
+  var docCookies = ... get the "docCookies" object here:
+  https://developer.mozilla.org/zh-CN/docs/DOM/document.cookie#A_little_framework.3A_a_complete_cookies_reader.2Fwriter_with_full_unicode_support
+*/
+
+var docCookies = new Proxy(docCookies, {
+  "get": function (oTarget, sKey) {
+    return oTarget[sKey] || oTarget.getItem(sKey) || undefined;
+  },
+  "set": function (oTarget, sKey, vValue) {
+    if (sKey in oTarget) { return false; }
+    return oTarget.setItem(sKey, vValue);
+  },
+  "deleteProperty": function (oTarget, sKey) {
+    if (sKey in oTarget) { return false; }
+    return oTarget.removeItem(sKey);
+  },
+  "enumerate": function (oTarget, sKey) {
+    return oTarget.keys();
+  },
+  "ownKeys": function (oTarget, sKey) {
+    return oTarget.keys();
+  },
+  "has": function (oTarget, sKey) {
+    return sKey in oTarget || oTarget.hasItem(sKey);
+  },
+  "defineProperty": function (oTarget, sKey, oDesc) {
+    if (oDesc && "value" in oDesc) { oTarget.setItem(sKey, oDesc.value); }
+    return oTarget;
+  },
+  "getOwnPropertyDescriptor": function (oTarget, sKey) {
+    var vValue = oTarget.getItem(sKey);
+    return vValue ? {
+      "value": vValue,
+      "writable": true,
+      "enumerable": true,
+      "configurable": false
+    } : undefined;
+  },
+});
+
+/* Cookies 测试 */
+
+alert(docCookies.my_cookie1 = "First value");
+alert(docCookies.getItem("my_cookie1"));
+
+docCookies.setItem("my_cookie1", "Changed value");
+alert(docCookies.my_cookie1);
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-objects', 'Proxy')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ES2016', '#sec-proxy-objects', 'Proxy')}}{{Spec2('ES2016')}}
{{SpecName('ES2017', '#sec-proxy-objects', 'Proxy')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-proxy-objects', 'Proxy')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Proxy", 2)}}

+ +

参考

+ + + +

版权声明

+ +

一些内容(如文本、例子)是复制自或修改自ECMAScript wiki(版权声明 CC 2.0 BY-NC-SA)。

diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/index.html new file mode 100644 index 0000000000..71a257174f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/index.html @@ -0,0 +1,118 @@ +--- +title: Proxy() 构造器 +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +--- +
{{JSRef}}
+ +
 Proxy() 构造器用来创建 {{jsxref("Proxy")}} 对象。
+ +

语法

+ +
new Proxy(target, handler)
+ +

参数

+ +
+
target
+
 Proxy 会对 target 对象进行包装。它可以是任何类型的对象,包括内置的数组,函数甚至是另一个代理对象。
+
handler
+
它是一个对象,它的属性提供了某些操作发生时所对应的处理函数。
+
+ +

描述

+ +

我们可以使用 Proxy() 构造器来创建一个新的 Proxy 对象。 构造器接收两个主要参数:

+ + + +

一个空的 handler 参数将会创建一个与被代理对象行为几乎完全相同的代理对象。通过在 handler 对象上定义一组处理函数,你可以自定义被代理对象的一些特定行为。例如, 通过定义 get() 你就可以自定义被代理对象的 属性访问器

+ +

处理函数

+ +

本节列出了所有你可以自定义的处理函数。处理函数有时候也被成为“劫持”(traps),这是由于它们会对底层被代理对象的调用进行劫持。

+ +
+
{{JSxRef("Global_Objects/Proxy/Proxy/apply", "handler.apply()")}}
+
函数调用劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/construct", "handler.construct()")}}
+
{{JSxRef("Operators/new", "new")}} 操作符劫持
+
{{JSxRef("Global_Objects/Proxy/Proxy/defineProperty", "handler.defineProperty()")}}
+
{{JSxRef("Object.defineProperty")}}调用劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/deleteProperty", "handler.deleteProperty()")}}
+
{{JSxRef("Operators/delete", "delete")}} 操作符劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/get", "handler.get()")}}
+
获取属性值劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
+
{{JSxRef("Object.getOwnPropertyDescriptor")}} 调用劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/getPrototypeOf", "handler.getPrototypeOf()")}}
+
{{JSxRef("Object.getPrototypeOf")}}调用劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/has", "handler.has()")}}
+
{{JSxRef("Operators/in", "in")}} 操作符劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/isExtensible", "handler.isExtensible()")}}
+
 {{JSxRef("Object.isExtensible")}}调用劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/ownKeys", "handler.ownKeys()")}}
+
{{JSxRef("Object.getOwnPropertyNames")}} 和{{JSxRef("Object.getOwnPropertySymbols")}}调用劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/preventExtensions", "handler.preventExtensions()")}}
+
{{JSxRef("Object.preventExtensions")}}调用劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/set", "handler.set()")}}
+
设置属性值劫持。
+
{{JSxRef("Global_Objects/Proxy/Proxy/setPrototypeOf", "handler.setPrototypeOf()")}}
+
{{JSxRef("Object.setPrototypeOf")}}调用劫持。
+
+ +

示例

+ +

选择性代理属性访问器

+ +

本例中,被代理对象有两个属性: notProxied  和 proxied 。我们定义了一个处理函数,它为 proxied 属性返回一个不同的值,而其他属性返回原值。

+ +
const target = {
+  notProxied: "original value",
+  proxied: "original value"
+};
+
+const handler = {
+  get: function(target, prop, receiver) {
+    if (prop === "proxied") {
+      return "replaced value";
+    }
+    return Reflect.get(...arguments);
+  }
+};
+
+const proxy = new Proxy(target, handler);
+
+console.log(proxy.notProxied); // "original value"
+console.log(proxy.proxied);    // "replaced value"
+ +

标准

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-proxy-constructor', 'Proxy constructor')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Proxy.Proxy")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/revocable/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/revocable/index.html new file mode 100644 index 0000000000..5f0095ae65 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/revocable/index.html @@ -0,0 +1,89 @@ +--- +title: Proxy.revocable() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/revocable +tags: + - ECMAScript6 + - JavaScript + - Method + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/revocable +--- +
{{JSRef("Global_Objects", "Proxy")}}
+ +

Proxy.revocable() 方法可以用来创建一个可撤销的代理对象。

+ +

语法

+ +
Proxy.revocable(target, handler);
+
+ +
+
target
+
将用 Proxy 封装的目标对象。可以是任何类型的对象,包括原生数组,函数,甚至可以是另外一个代理对象。
+
handler
+
一个对象,其属性是一批可选的函数,这些函数定义了对应的操作被执行时代理的行为。
+
+ +

返回值

+ +

返回一个包含了代理对象本身和它的撤销方法的可撤销 Proxy 对象。

+ +

描述

+ +

该方法的返回值是一个对象,其结构为: {"proxy": proxy, "revoke": revoke},其中:

+ +
+
proxy
+
表示新生成的代理对象本身,和用一般方式 new Proxy(target, handler) 创建的代理对象没什么不同,只是它可以被撤销掉。
+
revoke
+
撤销方法,调用的时候不需要加任何参数,就可以撤销掉和它一起生成的那个代理对象。
+
+ +

一旦某个代理对象被撤销,它将变得几乎完全不可调用,在它身上执行任何的可代理操作都会抛出 {{jsxref("TypeError")}} 异常(注意,可代理操作一共有 {{jsxref("Proxy", "14 种", "#Methods_of_the_handler_object")}},执行这 14 种操作以外的操作不会抛出异常)。一旦被撤销,这个代理对象便不可能被直接恢复到原来的状态,同时和它关联的目标对象以及处理器对象都有可能被垃圾回收掉。再次调用撤销方法 revoke() 则不会有任何效果,但也不会报错。

+ +

示例

+ +
var revocable = Proxy.revocable({}, {
+  get(target, name) {
+    return "[[" + name + "]]";
+  }
+});
+var proxy = revocable.proxy;
+proxy.foo;              // "[[foo]]"
+
+revocable.revoke();
+
+console.log(proxy.foo); // 抛出 TypeError
+proxy.foo = 1           // 还是 TypeError
+delete proxy.foo;       // 又是 TypeError
+typeof proxy            // "object",因为 typeof 不属于可代理操作
+
+ +

规范

+ + + + + + + + + + + + + + +
规范名称规范状态备注
{{SpecName('ES6', '#sec-proxy.revocable', 'Proxy Revocation Functions')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Proxy.revocable")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/rangeerror/index.html b/files/zh-cn/web/javascript/reference/global_objects/rangeerror/index.html new file mode 100644 index 0000000000..c46f557e24 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/rangeerror/index.html @@ -0,0 +1,163 @@ +--- +title: RangeError +slug: Web/JavaScript/Reference/Global_Objects/RangeError +translation_of: Web/JavaScript/Reference/Global_Objects/RangeError +--- +
{{JSRef}}
+ +

RangeError对象标明一个错误,当一个值不在其所允许的范围或者集合中。

+ +

语法

+ +
new RangeError([message[, fileName[, lineNumber]]])
+ +

参数

+ +
+
message
+
可选,可读的错误描述
+
fileName {{non-standard_inline}}
+
可选,包含造成异常代码的文件名
+
lineNumber {{non-standard_inline}}
+
可选,造成异常的代码所在的行数
+
+ +

描述

+ +

试图传递一个number参数给一个范围内不包含该number的函数时则会引发RangeError。当传递一个不合法的length值作为{{jsxref("Array")}} 构造器的参数创建数组,或者传递错误值到数值计算方法({{jsxref("Number.toExponential()")}},{{jsxref("Number.toFixed()")}} ,{{jsxref("Number.toPrecision()")}}),会出现RangeError。.

+ +

属性

+ +
+
{{jsxref("RangeError.prototype")}}
+
允许在RangeError对象上附加属性。
+
+ +

方法

+ +

RangeError全局对象没有自带方法,但它通过可以原型链继承一些方法。

+ +

RangeError实例

+ +

属性

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError/prototype', 'Properties')}}
+ +

方法

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError/prototype', 'Methods')}}
+ +

例子

+ +

使用RangeError

+ +
var check = function(num) {
+  if (num < MIN || num > MAX) {
+    throw new RangeError('Parameter must be between ' + MIN + ' and ' + MAX);
+  }
+};
+
+try {
+  check(500);
+}
+catch (e) {
+  if (e instanceof RangeError) {
+    // 处理越界错误
+  }
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.11.6.2', 'RangeError')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-native-error-types-used-in-this-standard-rangeerror', 'RangeError')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-native-error-types-used-in-this-standard-rangeerror', 'RangeError')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关连接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/rangeerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/rangeerror/prototype/index.html new file mode 100644 index 0000000000..ea09336ec0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/rangeerror/prototype/index.html @@ -0,0 +1,88 @@ +--- +title: RangeError.prototype +slug: Web/JavaScript/Reference/Global_Objects/RangeError/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/RangeError +--- +
{{JSRef}}
+ +
 
+ +
RangeError.prototype 属性表示 {{jsxref("RangeError")}} 构造函数的原型。
+ +
 
+ +
{{js_property_attributes(0, 0, 0)}}
+ +

描述

+ +

所有  {{jsxref("RangeError")}} 的实例都继承自 RangeError.prototype ,所以你可以使用这个属性来为所有的实例添加属性或方法。

+ +

属性

+ +
+
RangeError.prototype.constructor
+
指定了创建实例原型的函数
+
{{jsxref("Error.prototype.message", "RangeError.prototype.message")}}
+
错误信息。尽管 ECMA-262 规定了 {{jsxref("RangeError")}} 应该拥有一个 message 属性,但在 SpiderMonkey 中,该属性继承自 {{jsxref("Error.prototype.message")}}。
+
{{jsxref("Error.prototype.name", "RangeError.prototype.name")}}
+
错误名字,继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.fileName", "RangeError.prototype.fileName")}}
+
引起该错误的文件路径,继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.lineNumber", "RangeError.prototype.lineNumber")}}
+
引起该错误的行号,继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.columnNumber", "RangeError.prototype.columnNumber")}}
+
引起该错误的列号,继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.stack", "RangeError.prototype.stack")}}
+
堆栈跟踪记录,继承自 {{jsxref("Error")}}。
+
+ +

方法

+ +

尽管 {{jsxref("RangeError")}} 原型对象自身没有包含任何方法,但是 {{jsxref("RangeError")}} 实例却通过原型链继承到了一些方法。

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Defined as NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Defined as NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}Defined as NativeError.prototype.
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.RangeError")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/referenceerror/index.html b/files/zh-cn/web/javascript/reference/global_objects/referenceerror/index.html new file mode 100644 index 0000000000..1d42786c00 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/referenceerror/index.html @@ -0,0 +1,168 @@ +--- +title: ReferenceError +slug: Web/JavaScript/Reference/Global_Objects/ReferenceError +translation_of: Web/JavaScript/Reference/Global_Objects/ReferenceError +--- +
{{JSRef("Global_Objects", "Error", "EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError")}}
+ +

概述

+ +

ReferenceError(引用错误) 对象代表当一个不存在的变量被引用时发生的错误。

+ +

语法

+ +
new ReferenceError([message[, fileName[, lineNumber]]])
+ +

参数

+ +
+
message
+
可选。描述可读的错误信息
+
fileName {{non-standard_inline}}
+
可选。包含引起异常代码的文件名
+
lineNumber {{non-standard_inline}}
+
可选。引起异常的代码行号
+
+ +

描述

+ +

当你尝试引用一个未被定义的变量时,将会抛出一个 ReferenceError

+ +

属性

+ +
+
{{jsxref("ReferenceError.prototype")}}
+
Allows the addition of properties to an ReferenceError object.
+
+ +

方法

+ +

全局的 ReferenceError 本身并不包含有方法,但是他可以从原型链上继承一些方法

+ +

ReferenceError 实例

+ +

属性

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype', 'Properties')}}
+ +

方法

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype', 'Methods')}}
+ +

例子

+ +

例: 捕获一个 ReferenceError

+ +
try {
+  var a = undefinedVariable;
+} catch (e) {
+  console.log(e instanceof ReferenceError); // true
+  console.log(e.message);                   // "undefinedVariable is not defined"
+  console.log(e.name);                      // "ReferenceError"
+  console.log(e.fileName);                  // "Scratchpad/1"
+  console.log(e.lineNumber);                // 2
+  console.log(e.columnNumber);              // 6
+  console.log(e.stack);                     // "@Scratchpad/2:2:7\n"
+}
+
+ +

例: 创建一个 ReferenceError

+ +
try {
+  throw new ReferenceError('Hello', 'someFile.js', 10);
+} catch (e) {
+  console.log(e instanceof ReferenceError); // true
+  console.log(e.message);                   // "Hello"
+  console.log(e.name);                      // "ReferenceError"
+  console.log(e.fileName);                  // "someFile.js"
+  console.log(e.lineNumber);                // 10
+  console.log(e.columnNumber);              // 0
+  console.log(e.stack);                     // "@Scratchpad/2:2:9\n"
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
ECMAScript 3rd Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.11.6.3', 'ReferenceError')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-native-error-types-used-in-this-standard-referenceerror', 'ReferenceError')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/referenceerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/referenceerror/prototype/index.html new file mode 100644 index 0000000000..90f74dc4b1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/referenceerror/prototype/index.html @@ -0,0 +1,92 @@ +--- +title: ReferenceError.prototype +slug: Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype +tags: + - Error + - JavaScript + - Property + - Prototype + - ReferenceError +translation_of: Web/JavaScript/Reference/Global_Objects/ReferenceError +--- +
{{JSRef}}
+ +

ReferenceError.prototype 表示 {{jsxref("ReferenceError")}} 的原型构造器。

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

描述

+ +

所有{{jsxref("ReferenceError")}} 实例都继承自 ReferenceError.prototype. 你可以使用原型来为所有实例添加属性和方法。

+ +

属性

+ +
+
ReferenceError.prototype.constructor
+
创建一个实例原型的函数。
+
{{jsxref("Error.prototype.message", "ReferenceError.prototype.message")}}
+
错误信息。尽管ECMA-262 曾表示 {{jsxref("ReferenceError")}} 应该提供自己的 message 属性, 在 SpiderMonkey 中, 它继承自{{jsxref("Error.prototype.message")}}.
+
{{jsxref("Error.prototype.name", "ReferenceError.prototype.name")}}
+
错误名称. 继承自{{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "ReferenceError.prototype.fileName")}}
+
出现这个错误的路径. 继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "ReferenceError.prototype.lineNumber")}}
+
出现这个错误的行号. 继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "ReferenceError.prototype.columnNumber")}}
+
出现这个错误的列号. 继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "ReferenceError.prototype.stack")}}
+
堆栈追踪. 继承自 {{jsxref("Error")}}.
+
+ +

方法

+ +

尽管 {{jsxref("ReferenceError")}} 原型对象自身没有包括任何方法, {{jsxref("ReferenceError")}} 实例确实从原型链中继承了一些方法。

+ +

规格

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规格版本状态注释
{{SpecName('ES3')}}{{Spec2('ES3')}}初始定义
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}} +

Defined as NativeError.prototype.

+
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Defined as NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}Defined as NativeError.prototype.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.ReferenceError")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/apply/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/apply/index.html new file mode 100644 index 0000000000..d3cb19ec78 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/apply/index.html @@ -0,0 +1,101 @@ +--- +title: Reflect.apply() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/apply +tags: + - JavaScript + - Method + - Reference + - Reflect +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/apply +--- +
{{JSRef}}
+ +

静态方法 Reflect.apply() 通过指定的参数列表发起对目标(target)函数的调用。

+ +
{{EmbedInteractiveExample("pages/js/reflect-apply.html")}}
+ + + +

语法

+ +
Reflect.apply(target, thisArgument, argumentsList)
+
+ +

参数

+ +
+
target
+
目标函数。
+
thisArgument
+
target函数调用时绑定的this对象。
+
argumentsList
+
target函数调用时传入的实参列表,该参数应该是一个类数组的对象。
+
+ +

返回值

+ +

返回值是调用完带着指定参数和 this 值的给定的函数后返回的结果。

+ +

异常

+ +

如果 target 对象不可调用,抛出 {{jsxref("TypeError")}}。

+ +

描述

+ +

该方法与ES5中{{jsxref("Function.prototype.apply()")}}方法类似:调用一个方法并且显式地指定 this 变量和参数列表(arguments) ,参数列表可以是数组,或类似数组的对象。

+ +
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
+ +

使用 Reflect.apply 方法会使代码更加简洁易懂。

+ +

使用示例

+ +

Reflect.apply()

+ +
Reflect.apply(Math.floor, undefined, [1.75]);
+// 1;
+
+Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
+// "hello"
+
+Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index;
+// 4
+
+Reflect.apply("".charAt, "ponies", [3]);
+// "i"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.apply', 'Reflect.apply')}}{{Spec2('ES6')}}首次定义.
{{SpecName('ESDraft', '#sec-reflect.apply', 'Reflect.apply')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Reflect.apply")}}

+ +

相关连接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/construct/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/construct/index.html new file mode 100644 index 0000000000..8c6c4e2126 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/construct/index.html @@ -0,0 +1,189 @@ +--- +title: Reflect.construct() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/construct +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/construct +--- +
{{JSRef}}
+ +

Reflect.construct() 方法的行为有点像 new 操作符 构造函数 , 相当于运行 new target(...args).

+ +

语法

+ +
Reflect.construct(target, argumentsList[, newTarget])
+
+ +

参数

+ +
+
target
+
被运行的目标构造函数
+
argumentsList
+
类数组,目标构造函数调用时的参数。
+
newTarget {{optional_inline}}
+
作为新创建对象的原型对象的constructor属性, 参考 new.target 操作符,默认值为target。
+
+ +

返回值

+ +

target(如果newTarget存在,则为newTarget)函数为构造函数,argumentList为其初始化参数的对象实例。

+ +

异常

+ +

如果target或者newTarget不是构造函数,抛出{{jsxref("TypeError")}},异常。

+ +

描述

+ +

Reflect.construct允许你使用可变的参数来调用构造函数 ,这和使用new操作符搭配对象展开符调用一样。

+ +
var obj = new Foo(...args);
+var obj = Reflect.construct(Foo, args); 
+ +

Reflect.construct() vs Object.create()

+ +

在新语法Reflect出现之前,是通过明确指定构造函数和原型对象( 使用{{jsxref("Object.create()")}})来创建一个对象的。

+ +
function OneClass() {
+    this.name = 'one';
+}
+
+function OtherClass() {
+    this.name = 'other';
+}
+
+// 创建一个对象:
+var obj1 = Reflect.construct(OneClass, args, OtherClass);
+
+// 与上述方法等效:
+var obj2 = Object.create(OtherClass.prototype);
+OneClass.apply(obj2, args);
+
+console.log(obj1.name); // 'one'
+console.log(obj2.name); // 'one'
+
+console.log(obj1 instanceof OneClass); // false
+console.log(obj2 instanceof OneClass); // false
+
+console.log(obj1 instanceof OtherClass); // true
+console.log(obj2 instanceof OtherClass); // true
+ +

虽然两种方式结果相同,但在创建对象过程中仍一点不同。 

+ +

当使用Object.create()和{{jsxref("Function.prototype.apply()")}}时,如果不使用new操作符调用构造函数,构造函数内部的new.target值会指向undefined

+ +

当调用Reflect.construct()来创建对象,new.target值会自动指定到target(或者newTarget,前提是newTarget指定了)。

+ +
function OneClass() {
+    console.log('OneClass');
+    console.log(new.target);
+}
+function OtherClass() {
+    console.log('OtherClass');
+    console.log(new.target);
+}
+
+var obj1 = Reflect.construct(OneClass, args);
+// 输出:
+//     OneClass
+//     function OneClass { ... }
+
+var obj2 = Reflect.construct(OneClass, args, OtherClass);
+// 输出:
+//     OneClass
+//     function OtherClass { ... }
+
+var obj3 = Object.create(OtherClass.prototype);
+OneClass.apply(obj3, args);
+// 输出:
+//     OneClass
+//     undefined
+ +

举例

+ +

使用 Reflect.construct()

+ +
var d = Reflect.construct(Date, [1776, 6, 4]);
+d instanceof Date; // true
+d.getFullYear(); // 1776
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.construct', 'Reflect.construct')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-reflect.construct', 'Reflect.construct')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support49{{CompatGeckoDesktop(42)}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile(42)}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/defineproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/defineproperty/index.html new file mode 100644 index 0000000000..14882c24b9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/defineproperty/index.html @@ -0,0 +1,87 @@ +--- +title: Reflect.defineProperty() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty +tags: + - ECMAScript 2016 + - JavaScript + - Method + - Reflect +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty +--- +
{{JSRef}}
+ +

静态方法 Reflect.defineProperty() 基本等同于 {{jsxref("Object.defineProperty()")}} 方法,唯一不同是返回 {{jsxref("Boolean")}} 值。

+ +

语法

+ +
Reflect.defineProperty(target, propertyKey, attributes)
+
+ +

参数

+ +
+
target
+
目标对象。
+
propertyKey
+
要定义或修改的属性的名称。
+
attributes
+
要定义或修改的属性的描述。
+
+ +

返回值

+ +

 {{jsxref("Boolean")}} 值指示了属性是否被成功定义。

+ +

异常

+ +

如果target不是 {{jsxref("Object")}},抛出一个 {{jsxref("TypeError")}}。

+ +

描述

+ +

Reflect.defineProperty 方法允许精确添加或修改对象上的属性。更多的细节请参阅类似的{{jsxref("Object.defineProperty")}} 。

+ +
+

区别:Object.defineProperty 返回一个对象,或者如果属性没有被成功定义,抛出一个 {{jsxref("TypeError")}} 。 相比之下,Reflect.defineProperty方法只返回一个 {{jsxref("Boolean")}} ,来说明该属性是否被成功定义。

+
+ +

示例

+ +

使用 Reflect.defineProperty()

+ +
let obj = {}
+Reflect.defineProperty(obj, 'x', {value: 7})  // true
+obj.x                                         // 7
+ +

检查属性是否被成功定义

+ +

{{jsxref("Object.defineProperty")}} 方法,如果成功则返回一个对象,否则抛出一个 {{jsxref("TypeError")}} 。另外,当定义一个属性时,你也可以使用 try...catch 去捕获其中任何的错误。而因为 Reflect.defineProperty 返回 Boolean 值作为成功的标识,所以只能使用 if...else

+ +
if (Reflect.defineProperty(target, property, attributes)) {
+  // 成功
+} else {
+  // 失败
+}
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-reflect.defineproperty', 'Reflect.defineProperty')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Reflect.defineProperty")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/deleteproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/deleteproperty/index.html new file mode 100644 index 0000000000..3be36d7965 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/deleteproperty/index.html @@ -0,0 +1,134 @@ +--- +title: Reflect.deleteProperty() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty +--- +
{{JSRef}}
+ +

静态方法 Reflect.deleteProperty() 允许用于删除属性。它很像 delete operator ,但它是一个函数。

+ +

语法

+ +
Reflect.deleteProperty(target, propertyKey)
+
+ +

参数

+ +
+
target
+
删除属性的目标对象。
+
propertyKey
+
需要删除的属性的名称。
+
+ +

返回值

+ +

{{jsxref("Boolean")}} 值表明该属性是否被成功删除。

+ +

异常

+ +

抛出一个 {{jsxref("TypeError")}},如果target不是 {{jsxref("Object")}}。

+ +

描述

+ +

Reflect.deleteProperty 允许你删除一个对象上的属性。返回一个 {{jsxref("Boolean")}} 值表示该属性是否被成功删除。它几乎与非严格的 delete operator 相同。

+ +

示例

+ +

使用 Reflect.deleteProperty()

+ +
var obj = { x: 1, y: 2 };
+Reflect.deleteProperty(obj, "x"); // true
+obj; // { y: 2 }
+
+var arr = [1, 2, 3, 4, 5];
+Reflect.deleteProperty(arr, "3"); // true
+arr; // [1, 2, 3, , 5]
+
+// 如果属性不存在,返回 true
+Reflect.deleteProperty({}, "foo"); // true
+
+// 如果属性不可配置,返回 false
+Reflect.deleteProperty(Object.freeze({foo: 1}), "foo"); // false
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.deleteproperty', 'Reflect.deleteProperty')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-reflect.deleteproperty', 'Reflect.deleteProperty')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support49{{CompatGeckoDesktop(42)}}{{CompatNo}}{{CompatNo}}10
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}49{{CompatGeckoMobile(42)}}{{CompatNo}}{{CompatNo}}10
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/get/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/get/index.html new file mode 100644 index 0000000000..340178d61f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/get/index.html @@ -0,0 +1,90 @@ +--- +title: Reflect.get() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/get +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/get +--- +
{{JSRef}}
+ +

Reflect.get()方法与从 对象 (target[propertyKey]) 中读取属性类似,但它是通过一个函数执行来操作的。

+ +

语法

+ +
Reflect.get(target, propertyKey[, receiver])
+
+ +

参数

+ +
+
target
+
需要取值的目标对象
+
propertyKey
+
需要获取的值的键值
+
receiver
+
如果target对象中指定了getterreceiver则为getter调用时的this值。
+
+ +

返回值

+ +

属性的值。

+ +

异常

+ +

如果目标值类型不是 {{jsxref("Object")}},则抛出一个 {{jsxref("TypeError")}}。

+ +

描述

+ +

Reflect.get方法允许你从一个对象中取属性值。就如同属性访问器 语法,但却是通过函数调用来实现。

+ +

实例

+ +

使用 Reflect.get()

+ +
// Object
+var obj = { x: 1, y: 2 };
+Reflect.get(obj, "x"); // 1
+
+// Array
+Reflect.get(["zero", "one"], 1); // "one"
+
+// Proxy with a get handler
+var x = {p: 1};
+var obj = new Proxy(x, {
+  get(t, k, r) { return k + "bar"; }
+});
+Reflect.get(obj, "foo"); // "foobar"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.get', 'Reflect.get')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-reflect.get', 'Reflect.get')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Reflect.get")}}

+ +
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/getownpropertydescriptor/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/getownpropertydescriptor/index.html new file mode 100644 index 0000000000..e999254e32 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/getownpropertydescriptor/index.html @@ -0,0 +1,139 @@ +--- +title: Reflect.getOwnPropertyDescriptor() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor +--- +
{{JSRef}}
+ +

静态方法 Reflect.getOwnPropertyDescriptor() 与 {{jsxref("Object.getOwnPropertyDescriptor()")}} 方法相似。如果在对象中存在,则返回给定的属性的属性描述符。否则返回 {{jsxref("undefined")}}。 

+ +

语法

+ +
Reflect.getOwnPropertyDescriptor(target, propertyKey)
+
+ +

参数

+ +
+
target
+
需要寻找属性的目标对象。
+
propertyKey
+
获取自己的属性描述符的属性的名称。
+
+ +

返回值

+ +

如果属性存在于给定的目标对象中,则返回属性描述符;否则,返回 {{jsxref("undefined")}}。

+ +

异常

+ +

抛出一个 {{jsxref("TypeError")}},如果目标不是 {{jsxref("Object")}}。

+ +

描述

+ +

Reflect.getOwnPropertyDescriptor方法返回一个属性描述符,如果给定的属性存在于对象中,否则返回 {{jsxref("undefined")}} 。 与  {{jsxref("Object.getOwnPropertyDescriptor()")}} 的唯一不同在于如何处理非对象目标。

+ +

示例

+ +

使用 Reflect.getOwnPropertyDescriptor()

+ +
Reflect.getOwnPropertyDescriptor({x: "hello"}, "x");
+// {value: "hello", writable: true, enumerable: true, configurable: true}
+
+Reflect.getOwnPropertyDescriptor({x: "hello"}, "y");
+// undefined
+
+Reflect.getOwnPropertyDescriptor([], "length");
+// {value: 0, writable: true, enumerable: false, configurable: false}
+
+ +

与 Object.getOwnPropertyDescriptor() 的不同点

+ +

如果该方法的第一个参数不是一个对象(一个原始值),那么将造成 {{jsxref("TypeError")}} 错误。而对于 {{jsxref("Object.getOwnPropertyDescriptor")}},非对象的第一个参数将被强制转换为一个对象处理。

+ +
Reflect.getOwnPropertyDescriptor("foo", 0);
+// TypeError: "foo" is not non-null object
+
+Object.getOwnPropertyDescriptor("foo", 0);
+// { value: "f", writable: false, enumerable: true, configurable: false }
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.getownpropertydescriptor', 'Reflect.getOwnPropertyDescriptor')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-reflect.getownpropertydescriptor', 'Reflect.getOwnPropertyDescriptor')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support49{{CompatGeckoDesktop(42)}}{{CompatNo}}{{CompatNo}}10
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}49{{CompatGeckoMobile(42)}}{{CompatNo}}{{CompatNo}}10
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/getprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/getprototypeof/index.html new file mode 100644 index 0000000000..8189b3fb0f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/getprototypeof/index.html @@ -0,0 +1,84 @@ +--- +title: Reflect.getPrototypeOf() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf +--- +
{{JSRef}}
+ +

静态方法 Reflect.getPrototypeOf() 与 {{jsxref("Object.getPrototypeOf()")}} 方法几乎是一样的。都是返回指定对象的原型(即内部的 [[Prototype]] 属性的值)。

+ +

{{EmbedInteractiveExample("pages/js/reflect-getprototypeof.html")}}

+ +

语法

+ +
Reflect.getPrototypeOf(target)
+
+ +

参数

+ +
+
target
+
获取原型的目标对象。
+
+ +

返回值

+ +

给定对象的原型。如果给定对象没有继承的属性,则返回 {{jsxref("null")}}。

+ +

异常

+ +

如果 target 不是 {{jsxref("Object")}},抛出一个 {{jsxref("TypeError")}} 异常。

+ +

描述

+ +

Reflect.getPrototypeOf 返回指定对象的原型 (即内部的 [[Prototype]] 属性的值) 。

+ +

示例

+ +

使用 Reflect.getPrototypeOf()

+ +
Reflect.getPrototypeOf({}); // Object.prototype
+Reflect.getPrototypeOf(Object.prototype); // null
+Reflect.getPrototypeOf(Object.create(null)); // null
+
+ +

与 Object.getPrototypeOf() 比较

+ +
// 如果参数为 Object,返回结果相同
+Object.getPrototypeOf({})   // Object.prototype
+Reflect.getPrototypeOf({})  // Object.prototype
+
+// 在 ES5 规范下,对于非 Object,抛异常
+Object.getPrototypeOf('foo')   // Throws TypeError
+Reflect.getPrototypeOf('foo')  // Throws TypeError
+
+// 在 ES2015 规范下,Reflect 抛异常, Object 强制转换非 Object
+Object.getPrototypeOf('foo')   // String.prototype
+Reflect.getPrototypeOf('foo')  // Throws TypeError
+
+// 如果想要模拟 Object 在 ES2015 规范下的表现,需要强制类型转换
+Reflect.getPrototypeOf(Object('foo'))  // String.prototype
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-reflect.getprototypeof', 'Reflect.getPrototypeOf')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Reflect.getPrototypeOf")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/has/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/has/index.html new file mode 100644 index 0000000000..aaf55532e3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/has/index.html @@ -0,0 +1,133 @@ +--- +title: Reflect.has() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/has +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/has +--- +
{{JSRef}}
+ +

静态方法 Reflect.has() 作用与 in 操作符 相同。

+ +

句法

+ +
Reflect.has(target, propertyKey)
+
+ +

参数

+ +
+
target
+
目标对象.
+
propertyKey
+
属性名,需要检查目标对象是否存在此属性。
+
+ +

返回值

+ +

一个 {{jsxref("Boolean")}} 类型的对象指示是否存在此属性。

+ +

异常

+ +

如果目标对象并非{{jsxref("Object")}} 类型,抛出{{jsxref("TypeError")}}。

+ +

描述

+ +

Reflect.has 用于检查一个对象是否拥有某个属性, 相当于in 操作符 。

+ +

示例

+ +

使用 Reflect.has()

+ +
Reflect.has({x: 0}, "x"); // true
+Reflect.has({x: 0}, "y"); // false
+
+// 如果该属性存在于原型链中,返回true
+Reflect.has({x: 0}, "toString");
+
+// Proxy 对象的 .has() 句柄方法
+obj = new Proxy({}, {
+  has(t, k) { return k.startsWith("door"); }
+});
+Reflect.has(obj, "doorbell"); // true
+Reflect.has(obj, "dormitory"); // false
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.has', 'Reflect.has')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-reflect.has', 'Reflect.has')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support49{{CompatGeckoDesktop(42)}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile(42)}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关连接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/index.html new file mode 100644 index 0000000000..c9cb4a36cf --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/index.html @@ -0,0 +1,106 @@ +--- +title: Reflect +slug: Web/JavaScript/Reference/Global_Objects/Reflect +tags: + - ECMAScript 2015 + - JavaScript + - Overview + - Reflect +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect +--- +
{{JSRef}}
+ +

Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。这些方法与proxy handlers的方法相同。Reflect不是一个函数对象,因此它是不可构造的。

+ +

描述

+ +

与大多数全局对象不同Reflect并非一个构造函数,所以不能通过new运算符对其进行调用,或者将Reflect对象作为一个函数来调用。Reflect的所有属性和方法都是静态的(就像{{jsxref("Math")}}对象)。

+ +

Reflect 对象提供了以下静态方法,这些方法与proxy handler methods的命名相同.

+ +

其中的一些方法与 {{jsxref("Object")}}相同, 尽管二者之间存在 某些细微上的差别 .

+ +

静态方法

+ +
+
{{jsxref("Reflect.apply()", "Reflect.apply(targetthisArgumentargumentsList)")}}
+
对一个函数进行调用操作,同时可以传入一个数组作为调用参数。和 {{jsxref("Function.prototype.apply()")}} 功能类似。
+
{{jsxref("Reflect.construct()", "Reflect.construct(targetargumentsList[, newTarget])")}}
+
对构造函数进行 new 操作,相当于执行 new target(...args)
+
{{jsxref("Reflect.defineProperty()", "Reflect.defineProperty(targetpropertyKeyattributes)")}}
+
和 {{jsxref("Object.defineProperty()")}} 类似。如果设置成功就会返回 true
+
{{jsxref("Reflect.deleteProperty()", "Reflect.deleteProperty(targetpropertyKey)")}}
+
作为函数的delete操作符,相当于执行 delete target[name]
+
{{jsxref("Reflect.get()", "Reflect.get(targetpropertyKey[, receiver])")}}
+
获取对象身上某个属性的值,类似于 target[name]。
+
{{jsxref("Reflect.getOwnPropertyDescriptor()", "Reflect.getOwnPropertyDescriptor(targetpropertyKey)")}}
+
类似于 {{jsxref("Object.getOwnPropertyDescriptor()")}}。如果对象中存在该属性,则返回对应的属性描述符,  否则返回 {{jsxref("undefined")}}.
+
{{jsxref("Reflect.getPrototypeOf()", "Reflect.getPrototypeOf(target)")}}
+
类似于 {{jsxref("Object.getPrototypeOf()")}}。
+
{{jsxref("Reflect.has()", "Reflect.has(target, propertyKey)")}}
+
判断一个对象是否存在某个属性,和 in 运算符 的功能完全相同。
+
{{jsxref("Reflect.isExtensible()", "Reflect.isExtensible(target)")}}
+
类似于 {{jsxref("Object.isExtensible()")}}.
+
{{jsxref("Reflect.ownKeys()", "Reflect.ownKeys(target)")}}
+
返回一个包含所有自身属性(不包含继承属性)的数组。(类似于 {{jsxref("Object.keys()")}}, 但不会受enumerable影响).
+
{{jsxref("Reflect.preventExtensions()", "Reflect.preventExtensions(target)")}}
+
类似于 {{jsxref("Object.preventExtensions()")}}。返回一个{{jsxref("Boolean")}}。
+
{{jsxref("Reflect.set()", "Reflect.set(targetpropertyKeyvalue[, receiver])")}}
+
将值分配给属性的函数。返回一个{{jsxref("Boolean")}},如果更新成功,则返回true
+
{{jsxref("Reflect.setPrototypeOf()", "Reflect.setPrototypeOf(targetprototype)")}}
+
设置对象原型的函数. 返回一个 {{jsxref("Boolean")}}, 如果更新成功,则返回true。
+
+ +

Examples

+ +

检测一个对象是否存在特定属性

+ +
const duck = {
+  name: 'Maurice',
+  color: 'white',
+  greeting: function() {
+    console.log(`Quaaaack! My name is ${this.name}`);
+  }
+}
+
+Reflect.has(duck, 'color');
+// true
+Reflect.has(duck, 'haircut');
+// false
+ +

返回这个对象自身的属性

+ +
Reflect.ownKeys(duck);
+// [ "name", "color", "greeting" ]
+ +

为这个对象添加一个新的属性

+ +
Reflect.set(duck, 'eyes', 'black');
+// returns "true" if successful
+// "duck" now contains the property "eyes: 'black'"
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-reflect-object', 'Reflect')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Reflect")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/isextensible/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/isextensible/index.html new file mode 100644 index 0000000000..a04fbd5fb0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/isextensible/index.html @@ -0,0 +1,147 @@ +--- +title: Reflect.isExtensible() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible +--- +
{{JSRef}}
+ +

静态方法 Reflect.isExtensible() 判断一个对象是否可扩展 (即是否能够添加新的属性)。与它 {{jsxref("Object.isExtensible()")}} 方法相似,但有一些不同,详情可见 {{anch("Difference to Object.isExtensible()", "differences")}}。

+ +

语法

+ +
Reflect.isExtensible(target)
+
+ +

参数

+ +
+
target
+
检查是否可扩展的目标对象。
+
+ +

返回值

+ +

返回一个 {{jsxref("Boolean")}} 值表明该对象是否可扩展。

+ +

异常

+ +

抛出一个 {{jsxref("TypeError")}},如果对象不是 {{jsxref("Object")}}。

+ +

描述

+ +

Reflect.isExtensible 判断一个对象是否可扩展 (即是否能够添加新的属性)。它与 {{jsxref("Object.isExtensible()")}} 方法一样。

+ +

示例

+ +

使用 Reflect.isExtensible()

+ +

详情可见 {{jsxref("Object.isExtensible()")}}。

+ +
// New objects are extensible.
+var empty = {};
+Reflect.isExtensible(empty); // === true
+
+// ...but that can be changed.
+Reflect.preventExtensions(empty);
+Reflect.isExtensible(empty); // === false
+
+// Sealed objects are by definition non-extensible.
+var sealed = Object.seal({});
+Reflect.isExtensible(sealed); // === false
+
+// Frozen objects are also by definition non-extensible.
+var frozen = Object.freeze({});
+Reflect.isExtensible(frozen); // === false
+
+ +

与 Object.isExtensible() 的不同点

+ +

如果该方法的第一个参数不是一个对象(原始值),那么将造成一个 {{jsxref("TypeError")}} 异常。对于 {{jsxref("Object.isExtensible()")}},非对象的第一个参数会被强制转换为一个对象。

+ +
Reflect.isExtensible(1);
+// TypeError: 1 is not an object
+
+Object.isExtensible(1);
+// false
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.isextensible', 'Reflect.isExtensible')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-reflect.isextensible', 'Reflect.isExtensible')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support49{{CompatGeckoDesktop(42)}}{{CompatNo}}{{CompatNo}}10
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}49{{CompatGeckoMobile(42)}}{{CompatNo}}{{CompatNo}}10
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/ownkeys/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/ownkeys/index.html new file mode 100644 index 0000000000..bfa393f2ff --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/ownkeys/index.html @@ -0,0 +1,91 @@ +--- +title: Reflect.ownKeys() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys +tags: + - Reflect +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys +--- +
{{JSRef}}
+ +

静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。

+ +
{{EmbedInteractiveExample("pages/js/reflect-ownkeys.html")}}
+ + + +

语法

+ +
Reflect.ownKeys(target)
+
+ +

参数

+ +
+
target
+
获取自身属性键的目标对象。
+
+ +

返回值

+ +

由目标对象的自身属性键组成的 {{jsxref("Array")}}。 

+ +

异常

+ +

如果目标不是 {{jsxref("Object")}},抛出一个 {{jsxref("TypeError")}}。

+ +

描述

+ +

Reflect.ownKeys 方法返回一个由目标对象自身的属性键组成的数组。它的返回值等同于{{jsxref("Object.getOwnPropertyNames")}}(target).concat({{jsxref("Object.getOwnPropertySymbols")}}(target))。

+ +

示例

+ +

使用 Reflect.ownKeys()

+ +
Reflect.ownKeys({z: 3, y: 2, x: 1}); // [ "z", "y", "x" ]
+Reflect.ownKeys([]); // ["length"]
+
+var sym = Symbol.for("comet");
+var sym2 = Symbol.for("meteor");
+var obj = {[sym]: 0, "str": 0, "773": 0, "0": 0,
+           [sym2]: 0, "-1": 0, "8": 0, "second str": 0};
+Reflect.ownKeys(obj);
+// [ "0", "8", "773", "str", "-1", "second str", Symbol(comet), Symbol(meteor) ]
+// Indexes in numeric order,
+// strings in insertion order,
+// symbols in insertion order
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.ownkeys', 'Reflect.ownKeys')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-reflect.ownkeys', 'Reflect.ownKeys')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Reflect.ownKeys")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/preventextensions/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/preventextensions/index.html new file mode 100644 index 0000000000..7d24c17fe6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/preventextensions/index.html @@ -0,0 +1,93 @@ +--- +title: Reflect.preventExtensions() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions +--- +
{{JSRef}}
+ +

静态方法 Reflect.preventExtensions() 方法阻止新属性添加到对象 (例如:防止将来对对象的扩展被添加到对象中)。该方法与 {{jsxref("Object.preventExtensions()")}}相似,但有一些不同点。详情可见 {{anch("与_Object.preventExtensions_的不同点", "differences")}}。

+ +

{{EmbedInteractiveExample("pages/js/reflect-preventextensions.html")}}

+ +

语法

+ +
Reflect.preventExtensions(target)
+
+ +

参数

+ +
+
target
+
阻止扩展的目标对象。
+
+ +

返回值

+ +

返回一个 {{jsxref("Boolean")}} 值表明目标对象是否成功被设置为不可扩展。

+ +

异常

+ +

抛出一个 {{jsxref("TypeError")}} 错误,如果 target 不是 {{jsxref("Object")}}。

+ +

描述

+ +

Reflect.preventExtensions 方法阻止新属性添加到对象 (例如:防止将来对对象的扩展被添加到对象中)。该方法与  {{jsxref("Object.preventExtensions()")}} 方法相似。

+ +

示例

+ +

使用 Reflect.preventExtensions()

+ +

详情可见 {{jsxref("Object.preventExtensions()")}}.

+ +
// Objects are extensible by default.
+var empty = {};
+Reflect.isExtensible(empty); // === true
+
+// ...but that can be changed.
+Reflect.preventExtensions(empty);
+Reflect.isExtensible(empty); // === false
+
+ +

与 Object.preventExtensions() 的不同点

+ +

如果该方法的 target 参数不是一个对象(是原始值),那么将造成一个 {{jsxref("TypeError")}} 异常。 对于{{jsxref("Object.preventExtensions()")}} 方法, 非对象的 target 参数将被强制转换为对象。

+ +
Reflect.preventExtensions(1);
+// TypeError: 1 is not an object
+
+Object.preventExtensions(1);
+// 1
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.preventextensions', 'Reflect.preventExtensions')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-reflect.preventextensions', 'Reflect.preventExtensions')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Reflect.preventExtensions")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/set/index.html new file mode 100644 index 0000000000..9cb7bbe280 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/set/index.html @@ -0,0 +1,98 @@ +--- +title: Reflect.set() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/set +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/set +--- +
{{JSRef}}
+ +

静态方法 Reflect.set() 工作方式就像在一个对象上设置一个属性。

+ +

语法

+ +
Reflect.set(target, propertyKey, value[, receiver])
+
+ +

参数

+ +
+
target
+
设置属性的目标对象。
+
propertyKey
+
设置的属性的名称。
+
value
+
设置的值。
+
receiver
+
如果遇到 setterreceiver则为setter调用时的this值。
+
+ +

返回值

+ +

返回一个 {{jsxref("Boolean")}} 值表明是否成功设置属性。

+ +

异常

+ +

抛出一个 {{jsxref("TypeError")}},如果目标不是 {{jsxref("Object")}}。

+ +

描述

+ +

Reflect.set 方法允许你在对象上设置属性。它的作用是给属性赋值并且就像 property accessor 语法一样,但是它是以函数的方式。 

+ +

示例

+ +

使用 Reflect.set()

+ +
// Object
+var obj = {};
+Reflect.set(obj, "prop", "value"); // true
+obj.prop; // "value"
+
+// Array
+var arr = ["duck", "duck", "duck"];
+Reflect.set(arr, 2, "goose"); // true
+arr[2]; // "goose"
+
+// It can truncate an array.
+Reflect.set(arr, "length", 1); // true
+arr; // ["duck"];
+
+// With just one argument, propertyKey and value are "undefined".
+var obj = {};
+Reflect.set(obj); // true
+Reflect.getOwnPropertyDescriptor(obj, "undefined");
+// { value: undefined, writable: true, enumerable: true, configurable: true }
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-reflect.set', 'Reflect.set')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-reflect.set', 'Reflect.set')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Reflect.set")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/setprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/setprototypeof/index.html new file mode 100644 index 0000000000..c7dce35dd3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/setprototypeof/index.html @@ -0,0 +1,78 @@ +--- +title: Reflect.setPrototypeOf() +slug: Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf +translation_of: Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf +--- +
{{JSRef}}
+ +

除了返回类型以外,静态方法 Reflect.setPrototypeOf() 与 {{jsxref("Object.setPrototypeOf()")}} 方法是一样的。它可设置对象的原型(即内部的 [[Prototype]] 属性)为另一个对象或 {{jsxref("null")}},如果操作成功返回 true,否则返回 false

+ +

{{EmbedInteractiveExample("pages/js/reflect-setprototypeof.html")}}

+ +

语法

+ +
Reflect.setPrototypeOf(target, prototype)
+
+ +

参数

+ +
+
target
+
设置原型的目标对象。
+
prototype
+
对象的新原型(一个对象或 {{jsxref("null")}})。
+
+ +

返回值

+ +

返回一个 {{jsxref("Boolean")}} 值表明是否原型已经成功设置。

+ +

异常

+ +

如果 target 不是 {{jsxref("Object")}} ,或 prototype 既不是对象也不是 {{jsxref("null")}},抛出一个 {{jsxref("TypeError")}} 异常。

+ +

描述

+ +

Reflect.setPrototypeOf 方法改变指定对象的原型(即,内部的 [[Prototype]] 属性值)。

+ +

示例

+ +

使用 Reflect.setPrototypeOf()

+ +
Reflect.setPrototypeOf({}, Object.prototype); // true
+
+// It can change an object's [[Prototype]] to null.
+Reflect.setPrototypeOf({}, null); // true
+
+// Returns false if target is not extensible.
+Reflect.setPrototypeOf(Object.freeze({}), null); // false
+
+// Returns false if it cause a prototype chain cycle.
+var target = {};
+var proto = Object.create(target);
+Reflect.setPrototypeOf(target, proto); // false
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-reflect.setprototypeof', 'Reflect.setPrototypeOf')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Reflect.setPrototypeOf")}}

+ +

相关链接

+ + diff --git "a/files/zh-cn/web/javascript/reference/global_objects/reflect/\346\257\224\350\276\203_reflect_\345\222\214_object_\346\226\271\346\263\225/index.html" "b/files/zh-cn/web/javascript/reference/global_objects/reflect/\346\257\224\350\276\203_reflect_\345\222\214_object_\346\226\271\346\263\225/index.html" new file mode 100644 index 0000000000..43023eae7f --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/global_objects/reflect/\346\257\224\350\276\203_reflect_\345\222\214_object_\346\226\271\346\263\225/index.html" @@ -0,0 +1,134 @@ +--- +title: 比较 Reflect 和 Object 方法 +slug: Web/JavaScript/Reference/Global_Objects/Reflect/比较_Reflect_和_Object_方法 +tags: + - Guide + - JavaScript + - Object + - Overview + - Reflect +translation_of: >- + Web/JavaScript/Reference/Global_Objects/Reflect/Comparing_Reflect_and_Object_methods +--- +
{{jssidebar}}
+ +

ES2015中引入的 {{jsxref("Reflect")}} 对象是一个内置对象,提供了与JavaScript对象交互的方法。Reflect 上存在的一些静态函数也对应于ES2015之前的{{jsxref("Object")}}上可用的方法。尽管某些方法在行为上看似相似,但它们之间常常存在细微的差异。

+ +

下表详细介绍了Object 和 Reflect API上可用方法之间的差异。请注意,如果API中不存在某种方法,则将其标记为N/A。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method NameObjectReflect
defineProperty() +

{{jsxref("Object.defineProperty()")}} 返回传递给函数的对象。如果未在对象上成功定义属性,则返回TypeError

+
+

如果在对象上定义了属性,则{{jsxref("Reflect.defineProperty()")}}返回true,否则返回false

+
defineProperties() +

{{jsxref("Object.defineProperties()")}} 返回传递给函数的对象。如果未在对象上成功定义属性,则返回TypeError

+
N/A
set()N/A +

如果在对象上成功设置了属性,则{{jsxref("Reflect.set()")}}返回true,否则返回false。如果目标不是Object,则抛出TypeError

+
get()N/A +

{{jsxref("Reflect.get()")}}返回属性的值。如果目标不是Object,则抛出TypeError

+
deleteProperty()N/A +

如果属性从对象中删除,则{{jsxref("Reflect.deleteProperty()")}}返回true,否则返回false

+
getOwnPropertyDescriptor() +

如果传入的对象参数上存在{{jsxref("Object.getOwnPropertyDescriptor()")}} ,则会返回给定属性的属性描述符,如果不存在,则返回undefined

+
+

如果给定属性存在于对象上,则{{jsxref("Reflect.getOwnPropertyDescriptor()")}} 返回给定属性的属性描述符。如果不存在则返回undefined,如果传入除对象(原始值)以外的任何东西作为第一个参数,则返回TypeError

+
getOwnPropertyDescriptors() +

{{jsxref("Object.getOwnPropertyDescriptors()")}} 返回一个对象,其中包含每个传入对象的属性描述符。如果传入的对象没有拥有的属性描述符,则返回一个空对象。

+
N/A
getPrototypeOf() +

{{jsxref("Object.getPrototypeOf()")}}返回给定对象的原型。如果没有继承的原型,则返回null。在ES5中为非对象抛出TypeError,但在ES2015中强制为非对象。

+
+

{{jsxref("Reflect.getPrototypeOf()")}}返回给定对象的原型。如果没有继承的原型,则返回null,并为非对象抛出TypeError

+
setPrototypeOf() +

如果对象的原型设置成功,则{{jsxref("Object.setPrototypeOf()")}}返回对象本身。如果设置的原型不是Objectnull,或者被修改的对象的原型不可扩展,则抛出TypeError

+
+

如果在对象上成功设置了原型,则{{jsxref("Reflect.setPrototypeOf()")}} 返回true,否则返回false(包括原型是否不可扩展)。如果传入的目标不是Object,或者设置的原型不是Objectnull,则抛出TypeError

+
isExtensible() +

如果对象是可扩展的,则Object.isExtensible()返回true,否则返回false。如果第一个参数不是对象(原始值),则在ES5中抛出TypeError。在ES2015中,它将被强制为不可扩展的普通对象并返回false

+
+

如果对象是可扩展的,则{{jsxref("Reflect.isExtensible()")}} 返回true,否则返回false。如果第一个参数不是对象(原始值),则抛出TypeError

+
preventExtensions() +

{{jsxref("Object.preventExtensions()")}} 返回被设为不可扩展的对象。如果参数不是对象(原始值),则在ES5中抛出TypeError。在ES2015中,参数如为不可扩展的普通对象,然后返回对象本身。

+
+

returns true if the object has been made non-extensible, and false if it has not. Throws a TypeError if the argument is not an object (a primitive).

+ +

如果对象已变得不可扩展,则{{jsxref("Reflect.preventExtensions()")}} 返回true,否则返回false。如果参数不是对象(原始值),则抛出TypeError

+
keys() +

{{jsxref("Object.keys()")}}返回一个字符串数组,该字符串映射到目标对象自己的(可枚举)属性键。如果目标不是对象,则在ES5中抛出TypeError,但将非对象目标强制为ES2015中的对象

+
N/A
ownKeys()N/A +

{{jsxref("Reflect.ownKeys()")}}返回一个属性名称数组,该属性名称映射到目标对象自己的属性键。如果目标不是Object,则抛出TypeError

+
diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/@@match/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@match/index.html new file mode 100644 index 0000000000..28b4431659 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@match/index.html @@ -0,0 +1,109 @@ +--- +title: 'RegExp.prototype[@@match]()' +slug: Web/JavaScript/Reference/Global_Objects/RegExp/@@match +tags: + - JavaScript + - RegExp + - 正则 +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/@@match +--- +
{{JSRef}}
+ +

正则表达式匹配字符串时,[@@match]()方法用于获取匹配结果。

+ +

{{EmbedInteractiveExample("pages/js/regexp-prototype-@@match.html")}}

+ +

语法

+ +
regexp[Symbol.match](str)
+ +

参数

+ +
+
str
+
match 的目标参数是{{jsxref("String")}}
+
+ +

返回值

+ +

match 方法会返回一个数组,它包括整个匹配结果,和通过捕获组匹配到的结果,如果没有匹配到则返回null

+ +

描述

+ +

这个方法在 {{jsxref("String.prototype.match()")}} 的内部调用。例如,下面的两个方法返回相同结果。

+ +
'abc'.match(/a/);
+
+/a/[Symbol.match]('abc');
+ +

这个方法为自定义 RegExp 子类中的匹配行为而存在。

+ +

示例

+ +

直接调用

+ +

这个方法的使用方式和 {{jsxref("String.prototype.match()")}} 相同,不同之处是 this 和参数顺序。

+ +
var re = /[0-9]+/g;
+var str = '2016-01-02';
+var result = re[Symbol.match](str);
+console.log(result);  // ["2016", "01", "02"]
+
+ +

在子类中使用@@match

+ +

{{jsxref("RegExp")}} 的子类可以覆写 [@@match]()方法来修改默认行为。

+ +
class MyRegExp extends RegExp {
+  [Symbol.match](str) {
+    var result = RegExp.prototype[Symbol.match].call(this, str);
+    if (!result) return null;
+    return {
+      group(n) {
+        return result[n];
+      }
+    };
+  }
+}
+
+var re = new MyRegExp('([0-9]+)-([0-9]+)-([0-9]+)');
+var str = '2016-01-02';
+var result = str.match(re); // String.prototype.match calls re[@@match].
+console.log(result.group(1)); // 2016
+console.log(result.group(2)); // 01
+console.log(result.group(3)); // 02
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-regexp.prototype-@@match', 'RegExp.prototype[@@match]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+

{{Compat("javascript.builtins.RegExp.@@match")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/@@matchall/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@matchall/index.html new file mode 100644 index 0000000000..3cc1465704 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@matchall/index.html @@ -0,0 +1,89 @@ +--- +title: 'RegExp.prototype[@@matchAll]()' +slug: Web/JavaScript/Reference/Global_Objects/RegExp/@@matchAll +tags: + - JavaScript + - 正则表达式 +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/@@matchAll +--- +

{{JSRef}}

+ +

 [@@matchAll]方法返回对字符串使用正则表达式的所有匹配项。

+ +
\{{EmbedInteractiveExample("pages/js/regexp-prototype-@@matchall.html")}}
+ + + +

语法

+ +
regexp[Symbol.matchAll](str)
+ +

参数

+ +
+
str
+
一个{{jsxref("String")}}的匹配对象。
+
+ +

返回值

+ +

一个迭代器

+ +

描述

+ +

本方法在{{jsxref("String.prototype.matchAll()")}}中被内部调用。例如,以下两个示例返回相同的结果。

+ +
'abc'.matchAll(/a/);
+
+/a/[Symbol.matchAll]('abc');
+ +

本方法用于自定义RegExp子类中的匹配行为。

+ +

示例

+ +

直接调用

+ +

本方法的使用方法几乎与{{jsxref("String.prototype.matchAll()")}}相同,除了this 的不同以及参数顺序的的差异。

+ +
var re = /[0-9]+/g;
+var str = '2016-01-02';
+var result = re[Symbol.matchAll](str);
+
+console.log(Array.from(result, x => x[0]));
+// ["2016", "01", "02"]
+
+ +

在子类中使用@@matchAll

+ +

{{jsxref("RegExp")}}的子类可以重写[@@matchAll]()方法来修改默认行为。例如,返回一个{{jsxref("Array")}}而不是iterator:

+ +
class MyRegExp extends RegExp {
+  [Symbol.matchAll](str) {
+    var result = RegExp.prototype[Symbol.matchAll].call(this, str);
+    if (!result) {
+      return null;
+    } else {
+      return Array.from(result);
+    }
+  }
+}
+
+var re = new MyRegExp('([0-9]+)-([0-9]+)-([0-9]+)', 'g');
+var str = '2016-01-02|2019-03-07';
+var result = str.matchAll(re);
+console.log(result[0]); // [ "2016-01-02", "2016", "01", "02" ]
+console.log(result[1]); // [ "2019-03-07", "2019", "03", "07" ]
+
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.RegExp.@@matchAll")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/@@replace/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@replace/index.html new file mode 100644 index 0000000000..a8604f9415 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@replace/index.html @@ -0,0 +1,120 @@ +--- +title: 'RegExp.prototype[@@replace]()' +slug: Web/JavaScript/Reference/Global_Objects/RegExp/@@replace +tags: + - JavaScript + - RegExp + - 正则表达式 +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/@@replace +--- +
{{JSRef}}
+ +

 [@@replace]() 方法会在一个字符串中用给定的替换器,替换所有符合正则模式的匹配项,并返回替换后的新字符串结果。用来替换的参数可以是一个字符串或是一个针对每次匹配的回调函数。

+ +

{{EmbedInteractiveExample("pages/js/regexp-prototype-@@replace.html")}}

+ +

语法

+ +
regexp[Symbol.replace](str, newSubStr|function)
+ +

参数

+ +
+
str
+
正则替换的目标字符串。
+
newSubStr (replacement)
+
类型为 {{jsxref("String")}} 的替换器。支持大多数特殊的替换匹配模式; 见{{jsxref("String.prototype.replace()")}}页的{{jsxref("String.prototype.replace", "Specifying a string as a parameter", "#Specifying_a_string_as_a_parameter", 1)}}部分。
+
function (replacement)
+
生成新的子字符串的回调函数替换器。作用于该函数的参数的详细描述见{{jsxref("String.prototype.replace()")}}页的  {{jsxref("String.prototype.replace", "Specifying a function as a parameter", "#Specifying_a_function_as_a_parameter", 1)}} 部分。
+
+ +

返回值

+ +

用替换器替换相应匹配项后的新字符串。

+ +

描述

+ +

如果匹配模式也是{{jsxref("RegExp")}}对象,这个方法在 {{jsxref("String.prototype.replace()")}} 的内部调用。例如,下面的两个方法返回相同结果。

+ +
'abc'.replace(/a/, 'A');
+
+/a/[Symbol.replace]('abc', 'A');
+ +

该方法是为了在RegExp子类中自定义匹配的替换模式。

+ +

如果匹配模式不是一个{{jsxref("RegExp")}} 对象, {{jsxref("String.prototype.replace()")}} 就不会调用该方法,也不会创建一个 {{jsxref("RegExp")}}对象。

+ +

示例

+ +

直接调用

+ +

这个方法基本可以和 {{jsxref("String.prototype.replace()")}} 一样使用, 不同之处是 this 和参数顺序。

+ +
var re = /-/g;
+var str = '2016-01-01';
+var newstr = re[Symbol.replace](str, '.');
+console.log(newstr);  // 2016.01.01
+
+ +

在子类中使用@@replace

+ +

{{jsxref("RegExp")}} 的子类可以覆写 [@@replace]()方法来修改默认行为。

+ +
class MyRegExp extends RegExp {
+  constructor(pattern, flags, count) {
+    super(pattern, flags);
+    this.count = count;
+  }
+  [Symbol.replace](str, replacement) {
+    // Perform @@replace |count| times.
+    var result = str;
+    for (var i = 0; i < this.count; i++) {
+      result = RegExp.prototype[Symbol.replace].call(this, result, replacement);
+    }
+    return result;
+  }
+}
+
+var re = new MyRegExp('\\d', '', 3);
+var str = '01234567';
+var newstr = str.replace(re, '#'); // String.prototype.replace calls re[@@replace].
+console.log(newstr); // ###34567
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES6', '#sec-regexp.prototype-@@replace', 'RegExp.prototype[@@replace]')}}{{Spec2('ES6')}}初始定义
{{SpecName('ESDraft', '#sec-regexp.prototype-@@replace', 'RegExp.prototype[@@replace]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+

{{Compat("javascript.builtins.RegExp.@@replace")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/@@search/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@search/index.html new file mode 100644 index 0000000000..c88398e1a2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@search/index.html @@ -0,0 +1,153 @@ +--- +title: 'RegExp.prototype[@@search]()' +slug: Web/JavaScript/Reference/Global_Objects/RegExp/@@search +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/@@search +--- +
{{JSRef}}
+ +

[@@search]() 方法执行了一个在给定字符串中的一个搜索以取得匹配正则模式的项。

+ +

语法

+ +
regexp[Symbol.search](str)
+ +

参数

+ +
+
str
+
搜索的目标 {{jsxref("String")}}。
+
+ +

返回值

+ +
+
整数
+
如果成功的话,[@@search]() 返回该正则模式的第一个匹配项的在字符串中的位置索引。否则将返回-1。
+
+ +

描述

+ +

这个方法在 {{jsxref("String.prototype.search()")}} 的内部调用。例如,下面的两个方法返回相同结果。

+ +
'abc'.search(/a/);
+
+/a/[Symbol.search]('abc');
+ +

这个方法为自定义 RegExp 子类中的匹配行为而存在。

+ +

示例

+ +

直接调用

+ +

这个方法的使用方式和 {{jsxref("String.prototype.search()")}} 相同,不同之处是 this 和参数顺序。

+ +
var re = /-/g;
+var str = '2016-01-02';
+var result = re[Symbol.search](str);
+console.log(result);  // 4
+
+ +

在子类中使用@@search

+ +

{jsxref("RegExp")}} 的子类可以覆写 [@@search]()方法来修改默认行为。

+ +
class MyRegExp extends RegExp {
+  constructor(str) {
+    super(str)
+    this.pattern = str;
+  }
+  [Symbol.search](str) {
+    return str.indexOf(this.pattern);
+  }
+}
+
+var re = new MyRegExp('a+b');
+var str = 'ab a+b';
+var result = str.search(re); // String.prototype.search calls re[@@search].
+console.log(result); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-regexp.prototype-@@search', 'RegExp.prototype[@@search]')}}{{Spec2('ES6')}}初始定义
{{SpecName('ESDraft', '#sec-regexp.prototype-@@search', 'RegExp.prototype[@@search]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop(49)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile(49)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/@@species/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@species/index.html new file mode 100644 index 0000000000..49f72f06f7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@species/index.html @@ -0,0 +1,111 @@ +--- +title: 'get RegExp[@@species]' +slug: Web/JavaScript/Reference/Global_Objects/RegExp/@@species +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/@@species +--- +
{{JSRef}}
+ +

RegExp[@@species] 访问器属性返回RegExp 的构造器。

+ +

语法

+ +
RegExp[Symbol.species]
+
+ +

描述

+ +

species 访问器属性返回 RegExp 对象的默认构造器。子类构造器可能会覆盖它,来修改构造器的指派。

+ +

示例

+ +

species属性返回默认构造器函数,它是用于RegExp 对象的RegExp构造器:

+ +
RegExp[Symbol.species]; // 函数 RegExp()
+ +

在派生的正则类(也就是你自定义的正则类 MyRegExp)中,MyRegExp 的 species 是 MyRegExp 构造器。但是,你可能希望覆盖它,以便在你的派生类方法中,返回 RegExp 父类对象:

+ +
class MyRegExp extends RegExp {
+  // 将 MyRegExp species 覆盖为 RegExp 父类构造器
+  static get [Symbol.species]() { return RegExp; }
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-regexp-@@species', 'get RegExp [ @@species ]')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-get-regexp-@@species', 'get RegExp [ @@species ]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("49")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("49")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/@@split/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@split/index.html new file mode 100644 index 0000000000..b3bfa32317 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/@@split/index.html @@ -0,0 +1,151 @@ +--- +title: 'RegExp.prototype[@@split]()' +slug: Web/JavaScript/Reference/Global_Objects/RegExp/@@split +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/@@split +--- +
{{JSRef}}
+ +

[@@split]() 方法切割 {{jsxref("String")}} 对象为一个其子字符串的数组 。

+ +

语法

+ +
regexp[Symbol.split](str[, limit])
+ +

参数

+ +
+
str
+
切割操作的目标字符串
+
limit
+
+

可选。一个为了限制切割数量的特定整数。 [@@split]() 防范仍会切割每个匹配正则模式的匹配项,直到切割数量达到该限制数,除非提前切割完字符串。

+
+
+ +

返回值

+ +

包含其子字符串的{{jsxref("Array")}} 。

+ +

描述

+ +

如果切割器是一个{{jsxref("RegExp")}}对象,这个方法就将在 {{jsxref("String.prototype.split()")}} 的内部调用。例如,下面的两个方法返回相同结果。

+ +
'a-b-c'.split(/-/);
+
+/-/[Symbol.split]('a-b-c');
+ +

这个方法为自定义 RegExp 子类中的匹配行为而存在。

+ +

如果str参数不是一个{{jsxref("RegExp")}} 对象, {{jsxref("String.prototype.split()")}} 就不会调用该方法,也不会创建一个 {{jsxref("RegExp")}} 对象。示例

+ +

直接调用

+ +

这个方法的使用方式和 {{jsxref("String.prototype.split()")}} 相同,不同之处是 this 和参数顺序。

+ +
var re = /-/g;
+var str = '2016-01-02';
+var result = re[Symbol.split](str);
+console.log(result);  // ["2016", "01", "02"]
+
+ +

在子类中使用 @@split

+ +

{{jsxref("RegExp")}} 的子类可以覆写 [@@split]()方法来修改默认行为。

+ +
class MyRegExp extends RegExp {
+  [Symbol.split](str, limit) {
+    var result = RegExp.prototype[Symbol.split].call(this, str, limit);
+    return result.map(x => "(" + x + ")");
+  }
+}
+
+var re = new MyRegExp('-');
+var str = '2016-01-02';
+var result = str.split(re); // String.prototype.split calls re[@@split].
+console.log(result); // ["(2016)", "(01)", "(02)"]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-regexp.prototype-@@split', 'RegExp.prototype[@@split]')}}{{Spec2('ES6')}}初始定义
{{SpecName('ESDraft', '#sec-regexp.prototype-@@split', 'RegExp.prototype[@@split]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop(49)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile(49)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/compile/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/compile/index.html new file mode 100644 index 0000000000..e5b080a839 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/compile/index.html @@ -0,0 +1,131 @@ +--- +title: RegExp.prototype.compile() +slug: Web/JavaScript/Reference/Global_Objects/RegExp/compile +tags: + - Deprecated + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/compile +--- +
{{JSRef}} {{deprecated_header}}
+ +

已废弃的compile() 方法被用于在脚本执行过程中(重新)编译正则表达式。与RegExp构造函数基本一样。

+ +

语法

+ +
regexObj.compile(pattern, flags)
+ +

参数

+ +
+
pattern
+
正则表达式的文本 。
+
flags
+
+

如果指定,标志可以具有以下值的任意组合:

+ +
+
g
+
全局匹配
+
i
+
忽略大小写
+
m
+
多行;让开始和结束字符(^ 和 $)工作在多行模式工作(例如,^ 和 $ 可以匹配字符串中每一行的开始和结束(行是由 \n 或 \r 分割的),而不只是整个输入字符串的最开始和最末尾处。
+
y
+
黏度; 在目标字符串中,只从正则表达式的lastIndex属性指定的显示位置开始匹配(并且不试图从任何之后的索引匹配)。
+
+
+
+ +

描述

+ +

不推荐compile方法。你可以使用 RegExp 构造函数来得到相同效果。

+ +

示例

+ +

使用compile()

+ +

以下展示如何用新模式和新标志来重新编译正则表达式。

+ +
var regexObj = new RegExp("foo", "gi");
+regexObj.compile("new foo", "g");
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-regexp.prototype.compile', 'RegExp.prototype.compile')}}{{Spec2('ES6')}}Initial definition. Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
{{SpecName('ESDraft', '#sec-regexp.prototype.compile', 'RegExp.prototype.compile')}}{{Spec2('ESDraft')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/dotall/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/dotall/index.html new file mode 100644 index 0000000000..8608cfd1c2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/dotall/index.html @@ -0,0 +1,47 @@ +--- +title: RegExp.prototype.dotAll +slug: Web/JavaScript/Reference/Global_Objects/RegExp/dotAll +tags: + - JavaScript + - 修饰符 + - 正则表达式 +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/dotAll +--- +

{{JSRef}}{{Draft}}

+ +

dotAll 属性表明是否在正则表达式中一起使用"s"修饰符(引入/s修饰符,使得.可以匹配任意单个字符)。dotAll 是一个只读的属性,属于单个正则表达式实例。

+ +

{{JS_Property_Attributes(0, 0, 1)}}

+ +

描述

+ +

如果使用了"s"修饰符,dotAll 的值将返回{{JSxRef("Boolean")}}类型的true,否则将返回false。"s"修饰符表示,特殊字符"."应另外匹配字符串中的下述行终结符(line terminator characters),否则将会失配:

+ + + +

这实际上意味着"."将会匹配任意的单个Unicode Basic Multilingual Plane (BMP)字符。若要使其与astral字符(大于\uFFFF的Unicode字符)匹配,你应当使用"u"(Unicode)修饰符。一起使用这两个修饰符,"."将无一例外地匹配任意Unicode字符。

+ +

无法直接修改此属性。

+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.RegExp.dotAll")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/exec/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/exec/index.html new file mode 100644 index 0000000000..6648813f00 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/exec/index.html @@ -0,0 +1,199 @@ +--- +title: RegExp.prototype.exec() +slug: Web/JavaScript/Reference/Global_Objects/RegExp/exec +tags: + - '## lastIndex bug???' + - JavaScript + - Method + - Prototype + - RegExp + - Regular Expressions +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/exec +--- +
{{JSRef}}
+ +

exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 {{jsxref("null")}}。

+ +

在设置了 {{jsxref("RegExp.global", "global")}} 或 {{jsxref("RegExp.sticky", "sticky")}} 标志位的情况下(如 /foo/g or /foo/y),JavaScript {{jsxref("RegExp")}} 对象是有状态的。他们会将上次成功匹配后的位置记录在 {{jsxref("RegExp.lastIndex", "lastIndex")}} 属性中。使用此特性,exec() 可用来对单个字符串中的多次匹配结果进行逐条的遍历(包括捕获到的匹配),而相比之下, {{jsxref("String.prototype.match()")}} 只会返回匹配到的结果。

+ +

如果你只是为了判断是否匹配(true或 false),可以使用 {{jsxref("RegExp.test()")}} 方法,或者 {{jsxref("String.search()")}} 方法。

+ +
{{EmbedInteractiveExample("pages/js/regexp-prototype-exec.html")}}
+ + + +

语法

+ +
regexObj.exec(str)
+ +

参数

+ +
+
str
+
要匹配正则表达式的字符串。
+
+ +

返回值

+ +

如果匹配成功,exec() 方法返回一个数组(包含额外的属性 index 和 input ,参见下方表格),并更新正则表达式对象的 {{jsxref("RegExp.lastIndex", "lastIndex")}} 属性。完全匹配成功的文本将作为返回数组的第一项,从第二项起,后续每项都对应正则表达式内捕获括号里匹配成功的文本。

+ +

如果匹配失败,exec() 方法返回 {{jsxref("null")}},并将 {{jsxref("RegExp.lastIndex", "lastIndex")}} 重置为 0 。

+ +

描述

+ +

考虑以下示例:

+ +
// Match "quick brown" followed by "jumps", ignoring characters in between
+// Remember "brown" and "jumps"
+// Ignore case
+var re = /quick\s(brown).+?(jumps)/ig;
+var result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog');
+
+ +

下表列出这个脚本的返回值:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
对象属性/索引描述例子
result[0]匹配的全部字符串Quick Brown Fox Jumps
[1], ...[n ]括号中的分组捕获[1] = Brown
+ [2] = Jumps
index匹配到的字符位于原始字符串的基于0的索引值4
input原始字符串The Quick Brown Fox Jumps Over The Lazy Dog
relastIndex下一次匹配开始的位置25
ignoreCase是否使用了 "i" 标记使正则匹配忽略大小写true
global是否使用了 "g" 标记来进行全局的匹配.true
multiline +

是否使用了 "m" 标记使正则工作在多行模式(也就是,^ 和 $ 可以匹配字符串中每一行的开始和结束(行是由 \n 或 \r 分割的),而不只是整个输入字符串的最开始和最末尾处。)

+
false
source正则匹配的字符串quick\s(brown).+?(jumps)
+ +

示例

+ +

查找所有匹配

+ +

当正则表达式使用 "g" 标志时,可以多次执行 exec 方法来查找同一个字符串中的成功匹配。当你这样做时,查找将从正则表达式的 {{jsxref("RegExp.lastIndex", "lastIndex")}} 属性指定的位置开始。({{jsxref("RegExp.test", "test()")}} 也会更新 lastIndex 属性)。注意,即使再次查找的字符串不是原查找字符串时,{{jsxref("RegExp.lastIndex", "lastIndex")}} 也不会被重置,它依旧会从记录的 {{jsxref("RegExp.lastIndex", "lastIndex")}} 开始。

+ +

例如,你使用下面的脚本:

+ +
var myRe = /ab*/g;
+var str = 'abbcdefabh';
+var myArray;
+while ((myArray = myRe.exec(str)) !== null) {
+  var msg = 'Found ' + myArray[0] + '. ';
+  msg += 'Next match starts at ' + myRe.lastIndex;
+  console.log(msg);
+}
+
+ +

脚本运行结果如下:

+ +
Found abb. Next match starts at 3
+Found ab. Next match starts at 9
+
+ +
+

注意:不要把正则表达式字面量(或者{{jsxref("RegExp")}}构造器)放在 while 条件表达式里。由于每次迭代时 {{jsxref("RegExp.lastIndex", "lastIndex")}} 的属性都被重置,如果匹配,将会造成一个死循环。并且要确保使用了'g'标记来进行全局的匹配,否则同样会造成死循环。

+
+ +

结合 RegExp 字面量使用 exec()

+ +

你也可以直接使用 exec() 而不是创建一个 {{jsxref("RegExp")}}  对象:

+ +
var matches = /(hello \S+)/.exec('This is a hello world!');
+console.log(matches[1]);
+
+ +

运行上面的代码,控制台会输出"hello world!" 字符串。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.10.6.21', 'RegExp.exec')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-regexp.prototype.exec', 'RegExp.exec')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-regexp.prototype.exec', 'RegExp.exec')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.RegExp.exec")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/flags/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/flags/index.html new file mode 100644 index 0000000000..bb74a28131 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/flags/index.html @@ -0,0 +1,114 @@ +--- +title: RegExp.prototype.flags +slug: Web/JavaScript/Reference/Global_Objects/RegExp/flags +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/flags +--- +
{{JSRef}}
+ +

flags属性返回一个字符串,由当前正则表达式对象的标志组成。

+ +
{{js_property_attributes(0, 0, 1)}}
+ +

描述

+ +

flags属性中的标志以字典序排序(从左到右,即"gimuy")。

+ +

示例

+ +

使用flags

+ +
/foo/ig.flags;   // "gi"
+/bar/myu.flags;  // "muy"
+
+ +

Polyfill

+ +
if (RegExp.prototype.flags === undefined) {
+  Object.defineProperty(RegExp.prototype, 'flags', {
+    configurable: true,
+    get: function() {
+      return this.toString().match(/[gimuy]*$/)[0];
+    }
+  });
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-get-regexp.prototype.flags', 'RegExp.prototype.flags')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-get-regexp.prototype.flags', 'RegExp.prototype.flags')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("37")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/global/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/global/index.html new file mode 100644 index 0000000000..cddfc3724f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/global/index.html @@ -0,0 +1,107 @@ +--- +title: RegExp.prototype.global +slug: Web/JavaScript/Reference/Global_Objects/RegExp/global +tags: + - JavaScript + - Property + - Prototype + - RegExp +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/global +--- +
+ {{JSRef("Global_Objects", "RegExp")}}
+

概述

+

global 属性表明正则表达式是否使用了 "g" 标志。global 是一个正则表达式实例的只读属性。

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

global 的值是布尔对象,如果使用了 "g" 标志,则返回 true;否则返回 false。 "g" 标志意味着正则表达式应该测试字符串中所有可能的匹配。

+

你无法直接更改此属性。

+

示例

+

例子:使用 global

+
var regex = new RegExp("foo", "g")
+
+console.log(regex.global) // true
+
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 3rd Edition. Implemented in JavaScript 1.2.StandardInitial definition.
+ JavaScript 1.5: global is a property of a RegExp instance, not the RegExp object.
{{SpecName('ES5.1', '#sec-15.10.7.2', 'RegExp.prototype.global')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-get-regexp.prototype.global', 'RegExp.prototype.global')}}{{Spec2('ES6')}}global is now a prototype accessor property rather than an instance's own data property.
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/ignorecase/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/ignorecase/index.html new file mode 100644 index 0000000000..b2d0742626 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/ignorecase/index.html @@ -0,0 +1,107 @@ +--- +title: RegExp.prototype.ignoreCase +slug: Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase +tags: + - JavaScript + - Property + - Prototype + - RegExp +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase +--- +
+ {{JSRef("Global_Objects", "RegExp")}}
+

概述

+

ignoreCase 属性表明正则表达式是否使用了 "i" 标志。ignoreCase 是正则表达式实例的只读属性。

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

ignoreCase 的值是布尔对象,如果使用了"i" 标志,则返回 true;否则,返回 false。"i" 标志意味着在字符串进行匹配时,应该忽略大小写。

+

你无法直接更改此属性。

+

示例

+

例子:使用 ignoreCase

+
var regex = new RegExp("foo", "i")
+
+console.log(regex.ignoreCase) // true
+
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 3rd Edition. Implemented in JavaScript 1.2.StandardInitial definition.
+ JavaScript 1.5: ignoreCase is a property of a RegExp instance, not the RegExp object.
{{SpecName('ES5.1', '#sec-15.10.7.3', 'RegExp.prototype.ignoreCase')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-get-regexp.prototype.ignorecase', 'RegExp.prototype.ignoreCase')}}{{Spec2('ES6')}}ignoreCase is now a prototype accessor property rather than an instance's own data property.
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/index.html new file mode 100644 index 0000000000..77e10c7396 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/index.html @@ -0,0 +1,269 @@ +--- +title: RegExp +slug: Web/JavaScript/Reference/Global_Objects/RegExp +tags: + - Class + - JavaScript + - Reference + - RegExp + - Regular Expressions +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp +--- +
{{JSRef}}
+ +

RegExp 对象用于将文本与一个模式匹配。

+ +

有关正则表达式的介绍,请阅读 JavaScript指南中的正则表达式章节

+ +

描述

+ +

字面量和构造函数

+ +

有两种方法可以创建一个 RegExp 对象:一种是字面量,另一种是构造函数。

+ +
+
字面量
+
由斜杠包围而不是引号包围。
+
构造函数的字符串参数
+
由引号而不是斜杠包围。
+
+ +

以下三种表达式都会创建相同的正则表达式:

+ +
/ab+c/i;
+new RegExp('ab+c', 'i');
+new RegExp(/ab+c/, 'i');
+ +

当表达式被赋值时,字面量形式提供正则表达式的编译(compilation)状态,当正则表达式保持为常量时使用字面量。例如当你在循环中使用字面量构造一个正则表达式时,正则表达式不会在每一次迭代中都被重新编译(recompiled)。

+ +

而正则表达式对象的构造函数,如 new RegExp('ab+c') 提供了正则表达式运行时编译(runtime compilation)。如果你知道正则表达式模式将会改变,或者你事先不知道什么模式,而是从另一个来源获取,如用户输入,这些情况都可以使用构造函数。

+ +

构造函数中的标志参数(flags)

+ +

从 ECMAScript 6 开始,当第一个参数为正则表达式而第二个标志参数存在时,new RegExp(/ab+c/, 'i') 不再抛出 {{jsxref("TypeError")}} ("从另一个RegExp构造一个RegExp时无法提供标志")的异常,取而代之,将使用这些参数创建一个新的正则表达式。

+ +

当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \)。

+ +

比如,以下是等价的:

+ +
var re = new RegExp("\\w+");
+var re = /\w+/;
+ +

Perl-like RegExp 属性

+ +

请注意,{{jsxref("RegExp")}}属性有长名称和短名称(类似Perl)。两个名称总是引用同一个值。(Perl是JavaScript为其正则表达式建模的编程语言)。另请参见不推荐使用的RegExp属性。

+ +

构造函数

+ +
+
{{jsxref("RegExp/RegExp", "RegExp()")}}
+
创建一个新的 RegExp 对象。
+
+ +

静态属性

+ +
+
{{jsxref("RegExp.@@species", "get RegExp[@@species]")}}
+
该构造函数用于创建派生对象。
+
{{jsxref("RegExp.lastIndex")}}
+
该索引表示从哪里开始下一个匹配
+
+ +

实例属性

+ +
+
{{JSxRef("RegExp.prototype.flags")}}
+
含有 RegExp 对象 flags 的字符串。
+
{{JSxRef("RegExp.prototype.dotAll")}}
+
. 是否要匹配新行(newlines)。
+
{{JSxRef("RegExp.prototype.global")}}
+
针对字符串中所有可能的匹配项测试正则表达式,还是仅针对第一个匹配项。
+
+
+
{{JSxRef("RegExp.prototype.ignoreCase")}}
+
匹配文本的时候是否忽略大小写。
+
{{JSxRef("RegExp.prototype.multiline")}}
+
是否进行多行搜索。
+
{{JSxRef("RegExp.prototype.source")}}
+
正则表达式的文本。
+
{{JSxRef("RegExp.prototype.sticky")}}
+
搜索是否是 sticky。
+
{{JSxRef("RegExp.prototype.unicode")}}
+
Unicode 功能是否开启。
+
+ +

实例方法

+ +
+
{{JSxRef("RegExp.prototype.compile()")}}
+
运行脚本的期间(重新)编译正则表达式。
+
{{JSxRef("RegExp.prototype.exec()")}}
+
在该字符串中执行匹配项的搜索。
+
{{JSxRef("RegExp.prototype.test()")}}
+
该正则在字符串里是否有匹配。
+
{{JSxRef("RegExp.prototype.@@match()", "RegExp.prototype[@@match]()")}}
+
对给定字符串执行匹配并返回匹配结果。
+
{{JSxRef("RegExp.prototype.@@matchAll()", "RegExp.prototype[@@matchAll]()")}}
+
对给定字符串执行匹配,返回所有匹配结果。
+
{{JSxRef("RegExp.prototype.@@replace()", "RegExp.prototype[@@replace]()")}}
+
给定新的子串,替换所有匹配结果。
+
{{JSxRef("RegExp.prototype.@@search()", "RegExp.prototype[@@search]()")}}
+
在给定字符串中搜索匹配项,并返回在字符串中找到字符索引。
+
{{JSxRef("RegExp.prototype.@@split()", "RegExp.prototype[@@split]()")}}
+
通过将给定字符串拆分为子字符串,并返回字符串形成的数组。
+
{{JSxRef("RegExp.prototype.toString()")}}
+
返回表示指定对象的字符串。重写{{jsxref("Object.prototype.toString()")}}方法。
+
+ +

示例

+ +

使用正则改变数据结构

+ +

下例使用  {{jsxref("Global_Objects/String", "String")}} 的 {{jsxref("String.prototype.replace()", "replace()")}} 方法去匹配姓名 first last 输出新的格式 last, first

+ +

在替换的文本中,脚本中使用 $1 和 $2 指明括号里先前的匹配.

+ +
let re = /(\w+)\s(\w+)/;
+let str = "John Smith";
+let newstr = str.replace(re, "$2, $1");
+console.log(newstr);
+
+ +

这将显示 "Smith, John".

+ +

使用正则来划分带有多种行结束符和换行符的文本

+ +

对于不同的平台(Unix,Windows等等),其默认的行结束符是不一样的. 而下面的划分方式适用于所有平台。

+ +
let text = 'Some text\nAnd some more\r\nAnd yet\rThis is the end'
+let lines = text.split(/\r\n|\r|\n/)
+console.log(lines) // logs [ 'Some text', 'And some more', 'And yet', 'This is the end' ]
+
+ +

注意:在正则表达式中,以竖线分割的子模式的顺序会影响匹配结果。

+ +

在多行文本中使用正则表达式

+ +
let s = "Please yes\nmake my day!";
+
+s.match(/yes.*day/);
+// Returns null
+
+s.match(/yes[^]*day/);
+// Returns 'yes\nmake my day'
+ +

使用带有 sticky 标志的正则表达式

+ +

带有{{JSxRef("Global_Objects/RegExp/sticky", "sticky")}}标志的正则表达式将会从源字符串的{{jsxref("RegExp.prototype.lastIndex")}}位置开始匹配,也就是进行“粘性匹配”。

+ +
let str = '#foo#'
+let regex = /foo/y
+
+regex.lastIndex = 1
+regex.test(str)      // true
+regex.lastIndex = 5
+regex.test(str)      // false (lastIndex is taken into account with sticky flag)
+regex.lastIndex      // 0 (reset after match failure)
+ +

 sticky 标志和 global 标志的不同点

+ +

如果正则表达式有粘性 y 标志,下一次匹配一定在 lastIndex 位置开始;如果正则表达式有全局 g 标志,下一次匹配可能在 lastIndex 位置开始,也可能在这个位置的后面开始。

+ +
re = /\d/y;
+while (r = re.exec("123 456")) console.log(r, "AND re.lastIndex", re.lastIndex);
+
+// [ '1', index: 0, input: '123 456', groups: undefined ] AND re.lastIndex 1
+// [ '2', index: 1, input: '123 456', groups: undefined ] AND re.lastIndex 2
+// [ '3', index: 2, input: '123 456', groups: undefined ] AND re.lastIndex 3
+//   ... and no more match.
+ +

如果使用带有全局标志g的正则表达式re,就会捕获字符串中的所有6个数字,而非3个

+ +

使用正则表达式和 Unicode 字符

+ +

正如上面表格提到的,\w 或 \W 只会匹配基本的 ASCII 字符;如 a 到 zA 到 Z09_

+ +

为了匹配其他语言中的字符,如西里尔(Cyrillic)或 希伯来语(Hebrew),要使用 \uhhhhhhhh 表示以十六进制表示的字符的 Unicode 值。

+ +

下例展示了怎样从一个单词中分离出 Unicode 字符。

+ +
let text = "Образец text на русском языке";
+let regex = /[\u0400-\u04FF]+/g;
+
+let match = regex.exec(text);
+console.log(match[1]);  // prints "Образец"
+console.log(regex.lastIndex);  // prints "7"
+
+let match2 = regex.exec(text);
+console.log(match2[1]);  // prints "на" [did not print "text"]
+console.log(regex.lastIndex);  // prints "15"
+
+// and so on
+ +

Unicode属性转义特性引入了一种解决方案,它允许使用像\p{scx=Cyrl}这样简单的语句。这里有一个外部资源,用来获取 Unicode 中的不同区块范围:Regexp-unicode-block

+ +

从 URL 中提取子域名

+ +
var url = "http://xxx.domain.com";
+console.log(/[^.]+/.exec(url)[0].substr(7)); // logs "xxx"
+
+
+ +
+

使用浏览器内建的URL API而非正则表达式来解析URL是更好的做法

+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.10', 'RegExp')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-regexp-regular-expression-objects', 'RegExp')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.RegExp")}}

+ +

Firefox 特定版本提示

+ +

Starting with Gecko 34 {{geckoRelease(34)}}, in the case of a capturing group with quantifiers preventing its exercise, the matched text for a capturing group is now undefined instead of an empty string:

+ +
// Firefox 33 or older
+'x'.replace(/x(.)?/g, function(m, group) {
+  console.log("'group:" + group + "'");
+}); // 'group:'
+
+// Firefox 34 or newer
+'x'.replace(/x(.)?/g, function(m, group) {
+  console.log("'group:" + group + "'");
+}); // 'group:undefined'
+ +

注意,由于web兼容性 RegExp.$N 仍会返回一个空的字符串代替 undefined ({{bug(1053944)}}).

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/input/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/input/index.html new file mode 100644 index 0000000000..87b9ecb657 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/input/index.html @@ -0,0 +1,99 @@ +--- +title: RegExp.input ($_) +slug: Web/JavaScript/Reference/Global_Objects/RegExp/input +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/input +--- +
{{JSRef}} {{non-standard_header}}
+ +

input 非标准属性是正则表达式静态属性,含有正则表达式所匹配的字符串。RegExp.$_是这个属性的别名。

+ +

语法

+ +
RegExp.input
+RegExp.$_
+
+ +

描述

+ +

input 属性是静态的,并不是正则表达式独立对象的属性。反之,你应始终将其使用为 RegExp.input 或者 RegExp.$_。

+ +

当正则表达式上搜索的字符串发生改变,并且字符串匹配时,input 属性的值会修改。

+ +

示例

+ +

使用 input$_

+ +
var re = /hi/g;
+re.test('hi there!');
+RegExp.input;         // "hi there!"
+re.test('foo');       // 新测试,不匹配
+RegExp.$_;            // "hi there!"
+re.test('hi world!'); // 新测试,匹配
+RegExp.$_;            // "hi world!"
+
+ +

规范

+ +

非标准。并不是任何现行规范的一部分。

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/lastindex/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/lastindex/index.html new file mode 100644 index 0000000000..4931537cb6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/lastindex/index.html @@ -0,0 +1,128 @@ +--- +title: RegExp.lastIndex +slug: Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex +tags: + - JavaScript + - Property + - RegExp + - Regular Expressions +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex +--- +
+ {{JSRef("Global_Objects", "RegExp")}}
+

概述

+

lastIndex 是正则表达式的一个可读可写的整型属性,用来指定下一次匹配的起始索引。

+
+ {{js_property_attributes(1,0,0)}}
+

语法

+
lastIndex = regExpObj.lastIndex;
+

描述

+

只有正则表达式使用了表示全局检索的 "g" 标志时,该属性才会起作用。此时应用下面的规则:

+ +

示例

+

考虑下面的语句:

+
var re = /(hi)?/g;
+
+  
+

匹配空字符串

+
console.log(re.exec("hi"));
+console.log(re.lastIndex);
+
+  
+
+  
+

返回 ["hi", "hi"] ,lastIndex 等于 2。

+
console.log(re.exec("hi"));
+console.log(re.lastIndex);
+
+  
+
+  
+

返回 ["", undefined],即一个数组,其第 0 个元素为匹配的字符串。此种情况下为空字符串,是因为 lastIndex 为 2(且一直是 2),"hi" 长度为 2。

+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 3rd Edition. Implemented in JavaScript 1.2.StandardInitial definition.
+ JavaScript 1.5: lastIndex is a property of a RegExp instance, not the RegExp object.
{{SpecName('ES5.1', '#sec-15.10.7.5', 'RegExp.lastIndex')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-regexp-instances', 'RegExp.lastIndex')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/lastmatch/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/lastmatch/index.html new file mode 100644 index 0000000000..71a49daf44 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/lastmatch/index.html @@ -0,0 +1,98 @@ +--- +title: RegExp.lastMatch ($&) +slug: Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch +--- +
{{JSRef}} {{non-standard_header}}
+ +

lastMatch 非标准属性是正则表达式的静态和只读属性,含有最后匹配到的字符串。RegExp.$& 是这个属性的别名。

+ +

语法

+ +
RegExp.lastMatch
+RegExp['$&']
+
+ +

描述

+ +

lastMatch 属性是静态的,不是正则表达式独立对象的属性。反之,你应始终将其使用为 RegExp.lastMatch 或者 RegExp['$&']

+ +

lastMatch 属性的值是只读的,并且会在匹配成功时修改。

+ +

你不能使用属性访问器(RegExp.$&)来使用简写的别名,因为解析器在这里会将 "&" 看做表达式,并抛出 {{jsxref("SyntaxError")}} 。使用 方括号符号来访问属性。

+ +

示例

+ +

使用 lastMatch$&

+ +
var re = /hi/g;
+re.test('hi there!');
+RegExp.lastMatch; // "hi"
+RegExp['$&'];     // "hi"
+
+ +

规范

+ +

非标准。并不是任何现行规范的一部分。

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/lastparen/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/lastparen/index.html new file mode 100644 index 0000000000..0424c58ab3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/lastparen/index.html @@ -0,0 +1,98 @@ +--- +title: RegExp.lastParen ($+) +slug: Web/JavaScript/Reference/Global_Objects/RegExp/lastParen +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/lastParen +--- +
{{JSRef}} {{non-standard_header}}
+ +

lastParen 非标准属性是正则表达式的静态和只读属性,包含匹配到的最后一个子串(如果存在)。RegExp.$+是这一属性的别名。

+ +

语法

+ +
RegExp.lastParen
+RegExp['$+']
+
+ +

描述

+ +

lastParen 属性是静态的,不是正则表达式独立对象的属性。反之,你应始终将其使用为 RegExp.lastParen 或者 RegExp['$+']

+ +

lastParen 属性的值是只读的,并且会在匹配成功时修改。

+ +

你不能使用属性访问器(RegExp.$+)来使用简写的别名,因为解析器在这里会将 "+" 看做表达式,并抛出 {{jsxref("SyntaxError")}} 。使用 方括号符号来访问属性。

+ +

示例

+ +

使用 lastParen$+

+ +
var re = /(hi)/g;
+re.test('hi there!');
+RegExp.lastParen; // "hi"
+RegExp['$+'];     // "hi"
+
+ +

规范

+ +

非标准。并不是任何现行规范的一部分。

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/leftcontext/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/leftcontext/index.html new file mode 100644 index 0000000000..b2bf7596ce --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/leftcontext/index.html @@ -0,0 +1,98 @@ +--- +title: RegExp.leftContext ($`) +slug: Web/JavaScript/Reference/Global_Objects/RegExp/leftContext +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/leftContext +--- +
{{JSRef}} {{non-standard_header}}
+ +

leftContext 非标准属性是正则表达式的静态和只读属性,含有最新匹配的左侧子串。 RegExp.$` 是这个属性的别名。

+ +

语法

+ +
RegExp.leftContext
+RegExp['$`']
+
+ +

描述

+ +

leftContext 属性是静态的,不是正则表达式独立对象的属性。反之,你应始终将其使用为 RegExp.leftContext 或者 RegExp['$`']

+ +

leftContext 属性的值是只读的,并且会在匹配成功时修改。

+ +

你不能使用属性访问器(RegExp.$`)来使用简写的别名,因为解析器在这里会将其看做模板字符串的开始,并抛出 {{jsxref("SyntaxError")}} 。使用 方括号符号来访问属性。

+ +

示例

+ +

使用 leftContext$`

+ +
var re = /world/g;
+re.test('hello world!');
+RegExp.leftContext; // "hello "
+RegExp['$`'];       // "hello "
+
+ +

规范

+ +

非标准。并不是任何现行规范的一部分。

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/multiline/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/multiline/index.html new file mode 100644 index 0000000000..8f9a9adbd6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/multiline/index.html @@ -0,0 +1,108 @@ +--- +title: RegExp.prototype.multiline +slug: Web/JavaScript/Reference/Global_Objects/RegExp/multiline +tags: + - JavaScript + - Property + - Prototype + - RegExp + - Regular Expressions +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/multiline +--- +
+ {{JSRef("Global_Objects", "RegExp")}}
+

概述

+

multiline 属性表明正则表达式是否使用了 "m" 标志。multiline 是正则表达式实例的一个只读属性。

+
+ {{js_property_attributes(0,0,0)}}
+

描述

+

multiline 是一个布尔对象,如果使用了 "m" 标志,则返回 true;否则,返回 false。"m" 标志意味着一个多行输入字符串被看作多行。例如,使用 "m","^" 和 "$" 将会从只匹配正则字符串的开头或结尾,变为匹配字符串中任一行的开头或结尾。

+

你无法直接更改此属性。

+

示例

+

例子:使用 multiline

+
var regex = new RegExp("foo", "m")
+
+console.log(regex.multiline) // true
+
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 3rd Edition. Implemented in JavaScript 1.2.StandardInitial definition.
+ JavaScript 1.5: multiline is a property of a RegExp instance, not the RegExp object.
{{SpecName('ES5.1', '#sec-15.10.7.4', 'RegExp.prototype.multiline')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-get-regexp.prototype.multiline', 'RegExp.prototype.multiline')}}{{Spec2('ES6')}}multiline is now a prototype accessor property rather than an instance's own data property.
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/n/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/n/index.html new file mode 100644 index 0000000000..5101f73b28 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/n/index.html @@ -0,0 +1,110 @@ +--- +title: RegExp.$1-$9 +slug: Web/JavaScript/Reference/Global_Objects/RegExp/n +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/n +--- +
{{JSRef}} {{non-standard_header}}
+ +

非标准$1, $2, $3, $4, $5, $6, $7, $8, $9 属性是包含括号子串匹配的正则表达式的静态和只读属性。

+ +

语法

+ +
RegExp.$1
+RegExp.$2
+RegExp.$3
+RegExp.$4
+RegExp.$5
+RegExp.$6
+RegExp.$7
+RegExp.$8
+RegExp.$9
+
+ +

描述

+ +

$1, ..., $9 属性是静态的, 他不是独立的的正则表达式属性. 所以, 我们总是像这样子使用他们RegExp.$1, ..., RegExp.$9.

+ +

属性的值是只读的而且只有在正确匹配的情况下才会改变.

+ +

括号匹配项是无限的, 但是RegExp对象能捕获的只有九个. 你可以通过返回一个数组索引来取得所有的括号匹配项.

+ +

这些属性可以在{{jsxref("String.replace")}} 方法中替换字符串. 在这种情况下, 不用在前面加上RegExp。下面的例子将详细说明. 当正则表达式中不包含括号, 脚本中的 $n's 就是字面上的意思 (当n是正整数).

+ +

例子

+ +

$n 在 String.replace中的应用

+ +

以下脚本用 {{jsxref("String.prototype.replace()", "replace()")}} 方法去匹配一个first last格式的 name{{jsxref("String")}} 实例 输出last first格式. 在替换文本里, 脚本用 $1 和 $2 表示正则表达式中的括号匹配项的结果.

+ +
var re = /(\w+)\s(\w+)/;
+var str = 'John Smith';
+str.replace(re, '$2, $1'); // "Smith, John"
+RegExp.$1; // "John"
+RegExp.$2; // "Smith"
+
+ +

技术指标

+ +

非标准. 不属于当前的任何规范.

+ +

浏览器适配

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/prototype/index.html new file mode 100644 index 0000000000..e841c0e72d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/prototype/index.html @@ -0,0 +1,152 @@ +--- +title: RegExp.prototype +slug: Web/JavaScript/Reference/Global_Objects/RegExp/prototype +tags: + - JavaScript + - Property + - RegExp +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp +--- +

{{JSRef("Global_Objects", "RegExp")}}

+

概述

+

RegExp.prototype 属性表示 {{jsxref("Global_Objects/RegExp", "RegExp")}} 构造函数的原型对象。

+

描述

+

查看 {{jsxref("Global_Objects/RegExp", "RegExp")}} 了解更多关于 RegExp 实例的说明。

+

RegExp 实例继承 RegExp.prototype。修改该原型对象上的属性或方法会影响到所有的 RegExp 实例。

+

属性

+

查看已废弃的RegExp属性

+

注意,RegExp 对象的几个属性既有完整的长属性名,也有对应的类 Perl 的短属性名。两个属性都有着同样的值。JavaScript 的正则语法就是基于 Perl 的。

+
+
+ RegExp.prototype.constructor
+
+ 创建该正则对象的构造函数。
+
+ {{jsxref("RegExp.prototype.global")}}
+
+ 是否开启全局匹配,也就是匹配目标字符串中所有可能的匹配项,而不是只进行第一次匹配。
+
+ {{jsxref("RegExp.prototype.ignoreCase")}}
+
+ 在匹配字符串时是否要忽略字符的大小写。
+
+ {{jsxref("RegExp.prototype.lastIndex")}}
+
+ 下次匹配开始的字符串索引位置。
+
+ {{jsxref("RegExp.prototype.multiline")}}
+
+ 是否开启多行模式匹配(影响 ^ 和 $ 的行为)。
+
+ {{jsxref("RegExp.prototype.source")}}
+
+ 正则对象的源模式文本。
+
+ {{jsxref("RegExp.prototype.sticky")}} {{experimental_inline}}
+
+ 是否开启粘滞匹配。
+
+
+ {{ jsOverrides("Object", "properties", "constructor", "global", "ignoreCase", "lastIndex", "multiline", "source", "sticky") }}
+

方法

+

查看已废弃的RegExp方法

+
+
+ {{jsxref("RegExp.prototype.exec()")}}
+
+ 在目标字符串中执行一次正则匹配操作。
+
+ {{jsxref("RegExp.prototype.test()")}}
+
+ 测试当前正则是否能匹配目标字符串。
+
+ {{jsxref("RegExp.prototype.toSource()")}} {{non-standard_inline}}
+
+ 返回一个字符串,其值为该正则对象的字面量形式。覆盖了Object.prototype.toSource 方法.
+
+ {{jsxref("RegExp.prototype.toString()")}}
+
+ 返回一个字符串,其值为该正则对象的字面量形式。覆盖了{{jsxref("Object.prototype.toString()")}} 方法。
+
+
+ {{ jsOverrides("Object", "Methods", "exec", "test", "toSource", "toString") }}
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.10.5.1', 'RegExp')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-regexp.prototype', 'RegExp.prototype')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ +

 

diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/regexp/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/regexp/index.html new file mode 100644 index 0000000000..138ebf4ba7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/regexp/index.html @@ -0,0 +1,109 @@ +--- +title: RegExp() constructor +slug: Web/JavaScript/Reference/Global_Objects/RegExp/RegExp +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/RegExp +--- +
{{JSRef}}
+ +

RegExp 用于创建正则表达式对象,该对象用于将文本与一个模式匹配

+ +

阅读JavaScript指南中的正则表达式一节以了解正则表达式。

+ +
{{EmbedInteractiveExample("pages/js/regexp-constructor.html")}}
+ + + +

语法

+ +

可以使用字面量、构造函数和工厂方法来创建正则表达式

+ +
/pattern/flags
+new RegExp(pattern[, flags])
+RegExp(pattern[, flags])
+
+ +

参数

+ +
+
pattern
+
The text of the regular expression.
+
As of ES5, this can also be another RegExp object or literal (for the two RegExp constructor notations only). Patterns may include special characters to match a wider range of values than would a literal string. 
+
flags
+
+

If specified, flags is a string that contains the flags to add.

+ +

Alternatively, if an object is supplied for the pattern, the flags string will replace any of that object's flags (and lastIndex will be reset to 0) (as of ES2015).

+ +

If flags is not specified and a regular expressions object is supplied, that object's flags (and lastIndex value) will be copied over.

+ +

flags may contain any combination of the following characters:

+ +
+
g (全局匹配)
+
Find all matches rather than stopping after the first match.
+
i (忽略大小写)
+
If u flag is also enabled, use Unicode case folding.
+
m (多行匹配)
+
Treat beginning and end characters (^ and $) as working over multiple lines. In other words, match the beginning or end of each line (delimited by \n or \r), not only the very beginning or end of the whole input string.
+
s (点号匹配所有字符)
+
Allows . to match newlines.
+
u (unicode)
+
Treat pattern as a sequence of Unicode code points. (See also Binary strings).
+
y (sticky,粘性匹配)
+
Matches only from the index indicated by the lastIndex property of this regular expression in the target string. Does not attempt to match from any later indexes.
+
+
+
+ +

例子

+ +

字面量和构造函数

+ +

There are two ways to create a RegExp object: a literal notation and a constructor.

+ + + +

The following three expressions create the same regular expression:

+ +
/ab+c/i
+new RegExp(/ab+c/, 'i') // literal notation
+new RegExp('ab+c', 'i') // constructor
+
+ +

The literal notation results in compilation of the regular expression when the expression is evaluated. Use literal notation when the regular expression will remain constant. For example, if you use literal notation to construct a regular expression used in a loop, the regular expression won't be recompiled on each iteration.

+ +

The constructor of the regular expression object—for example, new RegExp('ab+c')—results in runtime compilation of the regular expression. Use the constructor function when you know the regular expression pattern will be changing, or you don't know the pattern and are getting it from another source, such as user input.

+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-regexp-constructor', 'RegExp constructor')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.RegExp.RegExp")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/rightcontext/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/rightcontext/index.html new file mode 100644 index 0000000000..5426301369 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/rightcontext/index.html @@ -0,0 +1,98 @@ +--- +title: RegExp.rightContext ($') +slug: Web/JavaScript/Reference/Global_Objects/RegExp/rightContext +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/rightContext +--- +
{{JSRef}} {{non-standard_header}}
+ +

rightContext 非标准属性是正则表达式的静态和只读属性,含有最新匹配的右侧子串。 RegExp.$' 是这个属性的别名。

+ +

语法

+ +
RegExp.rightContext
+RegExp["$'"]
+
+ +

描述

+ +

rightContext 属性是静态的,不是正则表达式独立对象的属性。反之,你应始终将其使用为 RegExp.rightContext 或者 RegExp["$'"]

+ +

rightContext 属性的值是只读的,并且会在匹配成功时修改。

+ +

你不能使用属性访问器(RegExp.$')来使用简写的别名,因为解析器在这里会将其看做字符串的开始,并抛出 {{jsxref("SyntaxError")}}。使用 方括号符号来访问属性。

+ +

示例

+ +

使用 rightContext$'

+ +
var re = /hello/g;
+re.test('hello world!');
+RegExp.rightContext; // " world!"
+RegExp["$'"];       // " world!"
+
+ +

规范

+ +

非标准。并不是任何现行规范的一部分。

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/source/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/source/index.html new file mode 100644 index 0000000000..8f526e39ca --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/source/index.html @@ -0,0 +1,109 @@ +--- +title: RegExp.prototype.source +slug: Web/JavaScript/Reference/Global_Objects/RegExp/source +tags: + - JavaScript + - Property + - Prototype + - Reference + - RegExp + - Regular Expressions +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/source +--- +
{{JSRef("Global_Objects", "RegExp")}}
+ +

概述

+ +

source 属性返回一个值为当前正则表达式对象的模式文本的字符串,该字符串不会包含正则字面量两边的斜杠以及任何的标志字符。

+ +

示例

+ +
var regex = /fooBar/ig;
+
+console.log(regex.source); // "fooBar",不包含 /.../ 和 "ig"。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范名称规范状态备注
ECMAScript 3rd Edition.Standardsource 是正则对象自身的数据属性
{{SpecName('ES5.1', '#sec-15.10.7.1', 'RegExp.prototype.source')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-get-regexp.prototype.source', 'RegExp.prototype.source')}}{{Spec2('ES6')}}source 成为了正则对象原型上的一个访问器属性
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/sticky/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/sticky/index.html new file mode 100644 index 0000000000..f74b96499b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/sticky/index.html @@ -0,0 +1,86 @@ +--- +title: RegExp.prototype.sticky +slug: Web/JavaScript/Reference/Global_Objects/RegExp/sticky +tags: + - JavaScript + - RegExp + - 正则表达式 +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/sticky +--- +
{{JSRef}}
+ +

sticky 属性反映了搜索是否具有粘性( 仅从正则表达式的 {{jsxref("RegExp.lastIndex", "lastIndex")}} 属性表示的索引处搜索 )。sticky 是正则表达式对象的只读属性。

+ +

{{EmbedInteractiveExample("pages/js/regexp-prototype-sticky.html", "taller")}}

+ +
{{js_property_attributes(0, 0, 1)}}
+ +

描述

+ +

sticky 的值是 {{jsxref("Boolean")}} ,并在 y 标志使用时为真; 否则为假。y 标志指示,仅从正则表达式的 {{jsxref("RegExp.lastIndex", "lastIndex")}} 属性表示的索引处为目标字符串匹配(并且不会尝试从后续索引匹配)。如果一个表达式同时指定了 stickyglobal,其将会忽略 global 标志。

+ +

你不能直接更改这个属性,它是只读的。

+ +

例子

+ +

使用带 sticky 标志的正则表达式

+ +
var str = '#foo#';
+var regex = /foo/y;
+
+regex.lastIndex = 1;
+regex.test(str); // true (译注:此例仅当 lastIndex = 1 时匹配成功,这就是 sticky 的作用)
+regex.lastIndex = 5;
+regex.test(str); // false (lastIndex 被 sticky 标志考虑到,从而导致匹配失败)
+regex.lastIndex; // 0 (匹配失败后重置)
+
+ +

锚定的 sticky 标志

+ +

火狐的 SpiderMonkey 引擎的几个版本有一个 bug,处理 ^ 断言和 sticky 标志时,会允许使用了 sticky 标志的表达式从 ^ 断言开始匹配,这是不对的。这个 bug 是在 Firefox 3.6 之后的某个版本引入的(which had the sticky flag but not the bug)并于2015年修复。 可能正因为这个 bug, ES2015 规范 特别指出

+ +
+

当使用带有 y 标识的匹配模式时,^ 断言总是会匹配输入的开始位置或者(如果是多行模式)每一行的开始位置。

+
+ +

正确行为的示例:

+ +
var regex = /^foo/y;
+regex.lastIndex = 2;
+regex.test("..foo");   // false - 索引2不是字符串的开始
+
+var regex2 = /^foo/my;
+regex2.lastIndex = 2;
+regex2.test("..foo");  // false - 索引2不是字符串或行的开始
+regex2.lastIndex = 2;
+regex2.test(".\nfoo"); // true - 索引2是行的开始
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-get-regexp.prototype.sticky', 'RegExp.prototype.sticky')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.RegExp.sticky")}}

+ +
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/test/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/test/index.html new file mode 100644 index 0000000000..d742f6c172 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/test/index.html @@ -0,0 +1,128 @@ +--- +title: RegExp.prototype.test() +slug: Web/JavaScript/Reference/Global_Objects/RegExp/test +tags: + - JavaScript + - Method + - Prototype + - RegExp + - Regular Expressions +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/test +--- +
{{JSRef}}
+ +

test() 方法执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 truefalse

+ +
{{EmbedInteractiveExample("pages/js/regexp-prototype-test.html", "taller")}}
+ + + +

语法

+ +
regexObj.test(str)
+ +

参数

+ +
+
str
+
用来与正则表达式匹配的字符串
+
+ +

返回值

+ +

如果正则表达式与指定的字符串匹配 ,返回true;否则false

+ +

描述

+ +

当你想要知道一个正则表达式是否与指定的字符串匹配时,就可以使用 test()(类似于 {{jsxref("String.prototype.search()")}} 方法),差别在于test返回一个布尔值,而 search 返回索引(如果找到)或者-1(如果没找到);若想知道更多信息(然而执行比较慢),可使用{{jsxref("RegExp.prototype.exec()", "exec()")}} 方法(类似于 {{jsxref("String.prototype.match()")}} 方法)。 和 {{jsxref("RegExp.prototype.exec()", "exec()")}} (或者组合使用),一样,在相同的全局正则表达式实例上多次调用test将会越过之前的匹配。

+ +

示例

+ +

使用 test()

+ +

一个简单的例子,测试 "hello" 是否包含在字符串的最开始,返回布尔值。

+ +
let str = 'hello world!';
+let result = /^hello/.test(str);
+console.log(result);
+// true
+
+ +

下例打印一条信息,该信息内容取决于是否成功通过指定测试:

+ +
function testinput(re, str){
+    var midstring;
+    if (re.test(str)) {
+        midstring = " contains ";
+    } else {
+        midstring = " does not contain ";
+    }
+    console.log(str + midstring + re.source);
+}
+
+ +

当设置全局标志的正则使用test()

+ +

如果正则表达式设置了全局标志,test() 的执行会改变正则表达式   lastIndex属性。连续的执行test()方法,后续的执行将会从 lastIndex 处开始匹配字符串,({{jsxref("RegExp.prototype.exec()", "exec()")}} 同样改变正则本身的 lastIndex属性值).

+ +

下面的实例表现了这种行为: 

+ +
var regex = /foo/g;
+
+// regex.lastIndex is at 0
+regex.test('foo'); // true
+
+// regex.lastIndex is now at 3
+regex.test('foo'); // false
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.10.6.3', 'RegExp.test')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-regexp.prototype.test', 'RegExp.test')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-regexp.prototype.test', 'RegExp.test')}}{{Spec2('ESDraft')}}
+ +

+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.RegExp.test")}}

+ +

Firefox特殊注意

+ +

在 Firefox 8之前, test() 被不正确地实现了;当无参数地调用时,它会匹配之前的输入值 (RegExp.input 属性),而不是字符串"undefined"。这已经被修正了;现在 /undefined/.test() 正确地返回true,而不是错误。

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/tosource/index.html new file mode 100644 index 0000000000..80f4972ca0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/tosource/index.html @@ -0,0 +1,44 @@ +--- +title: RegExp.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/RegExp/toSource +tags: + - JavaScript + - Method + - Non-standard + - Prototype + - RegExp +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/toSource +--- +

{{JSRef("Global_Objects", "RegExp")}}{{ Non-standard_header() }}

+ +

概述

+ +

返回一个字符串,代表当前对象的源代码

+ +

语法

+ +
regexObj.toSource()
+
+ +

描述

+ +

toSource方法返回值如下:

+ + + +
function RegExp() {
+    [native code]
+}
+
+ + + +

该方法通常由JavaScript内部隐含调用,而不会明确的出现在用户代码中.

+ +

相关链接

+ +

Object.prototype.toSource

diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/tostring/index.html new file mode 100644 index 0000000000..22aef815b4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/tostring/index.html @@ -0,0 +1,106 @@ +--- +title: RegExp.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/RegExp/toString +tags: + - JavaScript + - Method + - Prototype + - RegExp +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/toString +--- +
+ {{JSRef("Global_Objects", "RegExp")}}
+

概述

+

toString() 返回一个表示该正则表达式的字符串。

+

语法

+
regexObj.toString()
+

参数

+

+

描述

+

{{jsxref("Global_Objects/RegExp", "RegExp")}} 对象覆盖了 {{jsxref("Global_Objects/Object", "Object")}} 对象的 toString() 方法,并没有继承 {{jsxref("Object.prototype.toString()")}}。对于 RegExp 对象,toString 方法返回一个该正则表达式的字符串形式。

+

示例

+

例子:使用 toString

+

下例输出 RegExp 对象的字符串值:

+
myExp = new RegExp("a+b+c");
+alert(myExp.toString());       // 显示 "/a+b+c/"
+
+foo = new RegExp("bar", "g");
+alert(foo.toString());         // 显示 "/bar/g"
+
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 3rd Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.9.5.2', 'RegExp.prototype.toString')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-regexp.prototype.tostring', 'RegExp.prototype.toString')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

相关链接

+ diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/unicode/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/unicode/index.html new file mode 100644 index 0000000000..bd4253824c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/regexp/unicode/index.html @@ -0,0 +1,112 @@ +--- +title: RegExp.prototype.unicode +slug: Web/JavaScript/Reference/Global_Objects/RegExp/unicode +translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/unicode +--- +
{{JSRef}}
+ +

unicode 属性表明正则表达式带有"u" 标志。 unicode 是正则表达式独立实例的只读属性。

+ +
{{js_property_attributes(0, 0, 1)}}
+ +

描述

+ +

unicode 的值是 {{jsxref("Boolean")}},并且如果使用了 "u" 标志则为 true;否则为 false。"u" 标志开启了多种 Unicode 相关的特性。使用 "u" 标志,任何 Unicode 代码点的转义都会被解释。

+ +

你不能直接修改这个属性,它是只读的。

+ +

示例

+ +

使用 unicode 属性

+ +
var regex = new RegExp('\u{61}', 'u');
+
+console.log(regex.unicode); // true
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-get-regexp.prototype.unicode', 'RegExp.prototype.unicode')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-get-regexp.prototype.unicode', 'RegExp.prototype.unicode')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(50)}}12 (case folding 13){{CompatGeckoDesktop(46)}}{{CompatNo}}3710
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome(50)}}{{CompatGeckoMobile(46)}}{{CompatNo}}{{CompatVersionUnknown}}10
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/@@iterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/@@iterator/index.html new file mode 100644 index 0000000000..fa3f7c61e5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/@@iterator/index.html @@ -0,0 +1,81 @@ +--- +title: 'Set.prototype[@@iterator]()' +slug: Web/JavaScript/Reference/Global_Objects/Set/@@iterator +tags: + - ECMAScript2015 + - Iterator + - JavaScript + - Method + - set +translation_of: Web/JavaScript/Reference/Global_Objects/Set/@@iterator +--- +
{{JSRef}}
+ +

@@iterator 属性的初始值和 {{jsxref("Set.prototype.values()", "values")}} 属性的初始值是同一个函数。

+ +
{{EmbedInteractiveExample("pages/js/set-prototype-@@iterator.html")}}
+ + + +

Syntax

+ +
mySet[Symbol.iterator]
+ +

Return value

+ +

返回 Set iterator 函数,默认值是 {{jsxref("Set.prototype.values()", "values()")}} 函数。

+ +

Examples

+ +

Using [@@iterator]()

+ +
const mySet = new Set();
+mySet.add('0');
+mySet.add(1);
+mySet.add({});
+
+const setIter = mySet[Symbol.iterator]();
+
+console.log(setIter.next().value); // "0"
+console.log(setIter.next().value); // 1
+console.log(setIter.next().value); // Object
+
+ +

Using [@@iterator]() with for..of

+ +
const mySet = new Set();
+mySet.add('0');
+mySet.add(1);
+mySet.add({});
+
+for (const v of mySet) {
+  console.log(v);
+}
+
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-set.prototype-@@iterator', 'Set.prototype[@@iterator]')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Set.@@iterator")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/@@species/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/@@species/index.html new file mode 100644 index 0000000000..c950ccbf5a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/@@species/index.html @@ -0,0 +1,61 @@ +--- +title: 'get Set[@@species]' +slug: Web/JavaScript/Reference/Global_Objects/Set/@@species +tags: + - ECMAScript2015 + - JavaScript + - set +translation_of: Web/JavaScript/Reference/Global_Objects/Set/@@species +--- +
{{JSRef}}
+ +

Set[@@species] 访问器属性返回Set的构造函数.

+ +

描述

+ +

species 访问属性返回 Set 对象的默认构造函数. 子构造函数或许会重载这个属性以至改变构造函数的赋值.

+ +

示例

+ +

普通对象中的 Species

+ +

species 属性返回默认的构造函数, 它是Set 对象的构造函数:

+ +
Set[Symbol.species]; // function Set()
+ +

派生对象中的 Species

+ +

在一个派生集合对象中 (比如你自定义的MySet集合),  MySet 的species 属性 是 MySet 构造函数. 又或者, 你想要重写它, 让它能在你派生的类方法中能返回父级Set 对象:

+ +
class MySet extends Set {
+  // Overwrite MySet species to the parent Set constructor
+  static get [Symbol.species]() { return Set; }
+}
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-get-set-@@species', 'get Set [ @@species ]')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Set.@@species")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/add/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/add/index.html new file mode 100644 index 0000000000..255379d70c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/add/index.html @@ -0,0 +1,77 @@ +--- +title: Set.prototype.add() +slug: Web/JavaScript/Reference/Global_Objects/Set/add +tags: + - ECMAScript6 + - JavaScript + - Prototype + - set + - 原型 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Set/add +--- +
{{JSRef}} 
+ +

add() 方法用来向一个 Set 对象的末尾添加一个指定的值。

+ +
{{EmbedInteractiveExample("pages/js/set-prototype-add.html")}}
+ + + +

语法

+ +
mySet.add(value);
+ +

参数

+ +
+
value
+
必需。需要添加到 Set 对象的元素的值。
+
+ +

返回值

+ +

Set 对象本身

+ +

注意:不能添加重复的值

+ +

示例

+ +
var mySet = new Set();
+
+mySet.add(1);
+mySet.add(5).add("some text"); // 可以链式调用
+
+console.log(mySet);
+// Set [1, 5, "some text"]
+
+mySet.add(5).add(1);
+console.log(mySet);
+// Set [1, 5, "some text"]  // 重复的值没有被添加进去
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-set.prototype.add', 'Set.prototype.add')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Set.add")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/clear/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/clear/index.html new file mode 100644 index 0000000000..6103b63a67 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/clear/index.html @@ -0,0 +1,120 @@ +--- +title: Set.prototype.clear() +slug: Web/JavaScript/Reference/Global_Objects/Set/clear +tags: + - ECMAScript6 + - JavaScript + - Prototype + - set + - 原型 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Set/clear +--- +
{{JSRef}}
+ +

clear() 方法用来清空一个 Set 对象中的所有元素。

+ +

语法

+ +
mySet.clear();
+
+ +

返回值

+ +

{{jsxref("undefined")}}.

+ +

示例

+ +
var mySet = new Set();
+mySet.add(1);
+mySet.add("foo");
+
+mySet.size;       // 2
+mySet.has("foo"); // true
+
+mySet.clear();
+
+mySet.size;       // 0
+mySet.has("bar")  // false
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-set.prototype.clear', 'Set.prototype.clear')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-set.prototype.clear', 'Set.prototype.clear')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{CompatGeckoDesktop("19.0")}}11257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}25{{CompatGeckoMobile("19.0")}}{{ CompatNo() }}{{ CompatNo() }}8
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/delete/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/delete/index.html new file mode 100644 index 0000000000..5602ae7942 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/delete/index.html @@ -0,0 +1,120 @@ +--- +title: Set.prototype.delete() +slug: Web/JavaScript/Reference/Global_Objects/Set/delete +tags: + - ECMAScript6 + - JavaScript + - set + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Set/delete +--- +
{{JSRef}}
+ +

delete() 方法可以从一个 Set 对象中删除指定的元素。

+ +

语法

+ +
mySet.delete(value);
+ +

参数

+ +
+
value
+
将要删除的元素
+
+ +

返回值

+ +

成功删除返回 true,否则返回 false。

+ +

示例

+ +
var mySet = new Set();
+mySet.add("foo");
+
+mySet.delete("bar"); // 返回 false,不包含 "bar" 这个元素
+mySet.delete("foo"); // 返回 true,删除成功
+
+mySet.has("foo");    // 返回 false,"foo" 已经成功删除
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-set.prototype.delete', 'Set.prototype.delete')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-set.prototype.delete', 'Set.prototype.delete')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{CompatGeckoDesktop("13.0")}}11257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}38{{CompatGeckoMobile("13.0")}}{{ CompatNo() }}{{ CompatNo() }}8
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/entries/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/entries/index.html new file mode 100644 index 0000000000..f73a1e1a26 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/entries/index.html @@ -0,0 +1,113 @@ +--- +title: Set.prototype.entries() +slug: Web/JavaScript/Reference/Global_Objects/Set/entries +translation_of: Web/JavaScript/Reference/Global_Objects/Set/entries +--- +
{{JSRef}}
+ +

entries() 方法返回一个新的迭代器对象 ,这个对象的元素是类似 [value, value] 形式的数组,value 是集合对象中的每个元素,迭代器对象元素的顺序即集合对象中元素插入的顺序。由于集合对象不像 Map 对象那样拥有 key,然而,为了与 Map 对象的 API 形式保持一致,故使得每一个 entry 的 key 和 value 都拥有相同的值,因而最终返回一个 [value, value] 形式的数组。

+ +

语法

+ +
mySet.entries()
+ +

返回值

+ +

一个新的包含 [value, value] 形式的数组迭代器对象,value 是给定集合中的每个元素,迭代器 对象元素的顺序即集合对象中元素插入的顺序。

+ +

示例

+ +

使用 entries()

+ +
var mySet = new Set();
+mySet.add("foobar");
+mySet.add(1);
+mySet.add("baz");
+
+var setIter = mySet.entries();
+
+console.log(setIter.next().value); // ["foobar", "foobar"]
+console.log(setIter.next().value); // [1, 1]
+console.log(setIter.next().value); // ["baz", "baz"]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES6', '#sec-set.prototype.entries', 'Set.prototype.entries')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-set.prototype.entries', 'Set.prototype.entries')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性 

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{ CompatGeckoDesktop("24") }}{{CompatNo}}257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}38{{ CompatGeckoMobile("24") }}{{CompatNo}}{{CompatNo}}8
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/foreach/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/foreach/index.html new file mode 100644 index 0000000000..e89be3af36 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/foreach/index.html @@ -0,0 +1,145 @@ +--- +title: Set.prototype.forEach() +slug: Web/JavaScript/Reference/Global_Objects/Set/forEach +translation_of: Web/JavaScript/Reference/Global_Objects/Set/forEach +--- +
{{JSRef}}
+ +

forEach 方法会根据集合中元素的插入顺序,依次执行提供的回调函数。

+ +

语法

+ +
mySet.forEach(callback[, thisArg])
+ +

参数

+ +
+
callback
+
为集合中每个元素执行的回调函数,该函数接收三个参数:
+
+
+
currentValuecurrentKey{{optional_inline}}
+
currentValue 是正在被操作的元素。并且由于集合没有索引,所以 currentKey 也表示这个正在被操作的元素。
+
set{{optional_inline}}
+
调用当前 forEach 方法的集合对象
+
+
+
thisArg{{optional_inline}}
+
回调函数执行过程中的 this 值。
+
+ +

返回值

+ +

{{jsxref("undefined")}}.

+ +

描述

+ +

forEach 方法会依次为集合中的元素执行回调函数,就算元素的值是 undefined

+ +

回调函数有三个参数:

+ + + +

但是由于集合对象中没有索引(keys),所以前两个参数都是{{domxref("Set")}}中元素的值(values),之所以这样设计回调函数是为了和{{jsxref("Map.foreach", "Map")}} 以及{{jsxref("Array.forEach","Array")}}的 forEach 函数用法保持一致。

+ +

如果提供了一个 thisArg 参数给 forEach 函数,则参数将会作为回调函数中的 this值。否则 this 值为 undefined。回调函数中 this 的绑定是根据函数被调用时通用的 this 绑定规则来决定的

+ +

forEach 函数为集合对象中每个元素都执行一次回调;它不会返回任何值。

+ +

例子

+ +

输出集合对象的内容

+ +

以下代码依次打印集合对象的元素:

+ +
function logSetElements(value1, value2, set) {
+    console.log("s[" + value1 + "] = " + value2);
+}
+
+new Set(["foo", "bar", undefined]).forEach(logSetElements);
+
+// logs:
+// "s[foo] = foo"
+// "s[bar] = bar"
+// "s[undefined] = undefined"
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-set.prototype.foreach', 'Set.prototype.forEach')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatChrome(38) }}{{CompatGeckoDesktop("25.0")}}{{ CompatIE("11") }}257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}38{{CompatGeckoMobile("25.0")}}{{CompatNo}}{{CompatNo}}8
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/has/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/has/index.html new file mode 100644 index 0000000000..e9edc5d978 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/has/index.html @@ -0,0 +1,127 @@ +--- +title: Set.prototype.has() +slug: Web/JavaScript/Reference/Global_Objects/Set/has +tags: + - ECMAScript 2015 + - JavaScript + - set +translation_of: Web/JavaScript/Reference/Global_Objects/Set/has +--- +
{{JSRef("Global_Objects", "Set")}}
+ +

概述

+ +

has() 方法返回一个布尔值来指示对应的值value是否存在Set对象中。

+ +

语法

+ +
mySet.has(value);
+ +

参数

+ +
+
value
+
必需。用以测试该值是否存在于 Set 对象中。
+
+ +

返回值

+ +
+
Boolean
+
如果指定的值(value)存在于Set对象当中,返回true;否则返回 false
+
+ +

示例

+ +

使用 has 方法

+ +
var mySet = new Set();
+mySet.add('foo');
+
+mySet.has('foo');  // 返回 true
+mySet.has('bar');  // 返回 false
+
+var set1 = new Set();
+var obj1 = {'key1': 1};
+set1.add(obj1);
+
+set1.has(obj1);        // 返回 true
+set1.has({'key1': 1}); // 会返回 false,因为其是另一个对象的引用
+set1.add({'key1': 1}); // 现在 set1 中有2条(不同引用的)对象了
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-set.prototype.has', 'Set.prototype.has')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{CompatGeckoDesktop("13.0")}}11257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}38{{CompatGeckoMobile("13.0")}}{{ CompatNo() }}{{ CompatNo() }}iOS 8
+
+ +

相关连接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/index.html new file mode 100644 index 0000000000..6d4dca88c9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/index.html @@ -0,0 +1,273 @@ +--- +title: Set +slug: Web/JavaScript/Reference/Global_Objects/Set +tags: + - Class + - ECMAScript6 + - JavaScript + - set + - 全局对象 +translation_of: Web/JavaScript/Reference/Global_Objects/Set +--- +
{{ JSRef }}
+ +

Set 对象允许你存储任何类型的唯一值,无论是{{ Glossary('Primitive', '原始值') }}或者是对象引用。

+ +

简述

+ +

Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。

+ +

值的相等

+ +

因为 Set 中的值总是唯一的,所以需要判断两个值是否相等。在ECMAScript规范的早期版本中,这不是基于和===操作符中使用的算法相同的算法。具体来说,对于 Set s, +0 (+0 严格相等于-0)和-0是不同的值。然而,在 ECMAScript 2015规范中这点已被更改。有关详细信息,请参阅浏览器兼容性 表中的“Key equality for -0 and 0”。

+ +

另外,NaNundefined都可以被存储在Set 中, NaN之间被视为相同的值(NaN被认为是相同的,尽管 NaN !== NaN)。

+ +

Constructor

+ +
+
Set()
+
创建一个新的Set对象。
+
+ +

静态属性

+ +
+
{{jsxref("Set.@@species", "get Set[@@species]")}}
+
构造函数用来创建派生对象.
+
+ +

实例属性

+ +
+
{{jsxref("Set.prototype.size")}}
+
返回 Set 对象中的值的个数
+
+ +

实例方法

+ +
+
{{jsxref("Set.add", "Set.prototype.add(value)")}}
+
Set对象尾部添加一个元素。返回该Set对象。
+
{{jsxref("Set.prototype.clear()")}}
+
移除Set对象内的所有元素。
+
{{jsxref("Set.delete", "Set.prototype.delete(value)")}}
+
移除Set中与这个值相等的元素,返回Set.prototype.has(value)在这个操作前会返回的值(即如果该元素存在,返回true,否则返回false)。Set.prototype.has(value)在此后会返回false
+
{{jsxref("Set.prototype.entries()")}}
+
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值的[value, value]数组。为了使这个方法和Map对象保持相似, 每个值的键和值相等。
+
{{jsxref("Set.forEach", "Set.prototype.forEach(callbackFn[, thisArg])")}}
+
按照插入顺序,为Set对象中的每一个值调用一次callBackFn。如果提供了thisArg参数,回调中的this会是这个参数。
+
{{jsxref("Set.has", "Set.prototype.has(value)")}}
+
返回一个布尔值,表示该值在Set中存在与否。
+
{{jsxref("Set.prototype.keys()")}}
+
values()方法相同,返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
+
{{jsxref("Set.prototype.values()")}}
+
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
+
{{jsxref("Set.prototype.@@iterator()", "Set.prototype[@@iterator]()")}}
+
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
+
+ +

示例

+ +

使用Set对象

+ +
let mySet = new Set();
+
+mySet.add(1); // Set [ 1 ]
+mySet.add(5); // Set [ 1, 5 ]
+mySet.add(5); // Set [ 1, 5 ]
+mySet.add("some text"); // Set [ 1, 5, "some text" ]
+let o = {a: 1, b: 2};
+mySet.add(o);
+
+mySet.add({a: 1, b: 2}); // o 指向的是不同的对象,所以没问题
+
+mySet.has(1); // true
+mySet.has(3); // false
+mySet.has(5);              // true
+mySet.has(Math.sqrt(25));  // true
+mySet.has("Some Text".toLowerCase()); // true
+mySet.has(o); // true
+
+mySet.size; // 5
+
+mySet.delete(5);  // true,  从set中移除5
+mySet.has(5);     // false, 5已经被移除
+
+mySet.size; // 4, 刚刚移除一个值
+
+console.log(mySet);
+// logs Set(4) [ 1, "some text", {…}, {…} ] in Firefox
+// logs Set(4) { 1, "some text", {…}, {…} } in Chrome
+ +

迭代Set

+ +
// 迭代整个set
+// 按顺序输出:1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}
+for (let item of mySet) console.log(item);
+
+// 按顺序输出:1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}
+for (let item of mySet.keys()) console.log(item);
+
+// 按顺序输出:1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}
+for (let item of mySet.values()) console.log(item);
+
+// 按顺序输出:1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}
+//(键与值相等)
+for (let [key, value] of mySet.entries()) console.log(key);
+
+// 使用 Array.from 转换Set为Array
+var myArr = Array.from(mySet); // [1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}]
+
+// 如果在HTML文档中工作,也可以:
+mySet.add(document.body);
+mySet.has(document.querySelector("body")); // true
+
+// Set 和 Array互换
+mySet2 = new Set([1, 2, 3, 4]);
+mySet2.size;               // 4
+[...mySet2];               // [1,2,3,4]
+
+// 可以通过如下代码模拟求交集
+let intersection = new Set([...set1].filter(x => set2.has(x)));
+
+// 可以通过如下代码模拟求差集
+let difference = new Set([...set1].filter(x => !set2.has(x)));
+
+// 用forEach迭代
+mySet.forEach(function(value) {
+  console.log(value);
+});
+
+// 1
+// 2
+// 3
+// 4
+
+ +

实现基本集合操作

+ +
function isSuperset(set, subset) {
+    for (let elem of subset) {
+        if (!set.has(elem)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+function union(setA, setB) {
+    let _union = new Set(setA);
+    for (let elem of setB) {
+        _union.add(elem);
+    }
+    return _union;
+}
+
+function intersection(setA, setB) {
+    let _intersection = new Set();
+    for (let elem of setB) {
+        if (setA.has(elem)) {
+            _intersection.add(elem);
+        }
+    }
+    return _intersection;
+}
+
+function symmetricDifference(setA, setB) {
+    let _difference = new Set(setA);
+    for (let elem of setB) {
+        if (_difference.has(elem)) {
+            _difference.delete(elem);
+        } else {
+            _difference.add(elem);
+        }
+    }
+    return _difference;
+}
+
+function difference(setA, setB) {
+    let _difference = new Set(setA);
+    for (let elem of setB) {
+        _difference.delete(elem);
+    }
+    return _difference;
+}
+
+//Examples
+let setA = new Set([1, 2, 3, 4]),
+    setB = new Set([2, 3]),
+    setC = new Set([3, 4, 5, 6]);
+
+isSuperset(setA, setB);          // => true
+union(setA, setC);               // => Set [1, 2, 3, 4, 5, 6]
+intersection(setA, setC);        // => Set [3, 4]
+symmetricDifference(setA, setC); // => Set [1, 2, 5, 6]
+difference(setA, setC);          // => Set [1, 2]
+
+ +

 Array 相关

+ +
let myArray = ["value1", "value2", "value3"];
+
+// 用Set构造器将Array转换为Set
+let mySet = new Set(myArray);
+
+mySet.has("value1"); // returns true
+
+// 用...(展开操作符)操作符将Set转换为Array
+console.log([...mySet]); // 与myArray完全一致
+
+ +

数组去重

+ +
// Use to remove duplicate elements from the array
+const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
+console.log([...new Set(numbers)])
+// [2, 3, 4, 5, 6, 7, 32]
+
+ +

String 相关

+ +
let text = 'India';
+
+let mySet = new Set(text);  // Set {'I', 'n', 'd', 'i', 'a'}
+mySet.size;  // 5
+
+// 大小写敏感 & duplicate ommision
+new Set("Firefox")  // Set(7) [ "F", "i", "r", "e", "f", "o", "x" ]
+new Set("firefox")  // Set(6) [ "f", "i", "r", "e", "o", "x" ]
+
+ +

规范

+ + + + + + + + + + +
规范
{{ SpecName('ESDraft', '#sec-set-objects', 'Set') }}
+ +

浏览器兼容性

+ + + +

{{ Compat('javascript.builtins.Set') }}

+ +

参见

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/set/index.html new file mode 100644 index 0000000000..2ead74e30a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/set/index.html @@ -0,0 +1,73 @@ +--- +title: Set() constructor +slug: Web/JavaScript/Reference/Global_Objects/Set/Set +tags: + - Constructor + - JavaScript + - Reference + - set +translation_of: Web/JavaScript/Reference/Global_Objects/Set/Set +--- +
{{JSRef}}
+ +

Set 构造函数能让你创建 Set 对象,其可以存储任意类型的唯一值,无论是 primitive values 或者对象引用。

+ +
{{EmbedInteractiveExample("pages/js/set-prototype-constructor.html")}}
+ + + +

Syntax

+ +
new Set([iterable])
+ +

Parameters

+ +
+
iterable {{optional_inline}}
+
如果传递一个可迭代对象,它的所有元素将不重复地被添加到新的 Set中。
+
如果不指定此参数或其值为null,则新的 Set为空。
+
+ +

Return value

+ +

A new Set object.

+ +

Examples

+ +

Using the Set object

+ +
let mySet = new Set()
+
+mySet.add(1)           // Set [ 1 ]
+mySet.add(5)           // Set [ 1, 5 ]
+mySet.add(5)           // Set [ 1, 5 ]
+mySet.add('some text') // Set [ 1, 5, 'some text' ]
+let o = {a: 1, b: 2}
+mySet.add(o)
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-set-constructor', 'Set constructor')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Set.Set")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/size/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/size/index.html new file mode 100644 index 0000000000..a18e85fade --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/size/index.html @@ -0,0 +1,75 @@ +--- +title: Set.prototype.size +slug: Web/JavaScript/Reference/Global_Objects/Set/size +tags: + - ECMAScript 2015 + - JavaScript + - Property + - set +translation_of: Web/JavaScript/Reference/Global_Objects/Set/size +--- +
{{JSRef}}
+ +

Size属性将会返回{{jsxref("Set")}}对象中元素的个数。

+ +

{{EmbedInteractiveExample("pages/js/set-prototype-size.html")}}

+ + + +

描述

+ +

size的值是一个整数,表示Set对象有多少条目。size的集合访问函数是undefined; 你不能改变这个属性。

+ +

例子

+ +

使用size

+ +
var mySet = new Set();
+mySet.add(1);
+mySet.add(5);
+mySet.add("some text")
+
+mySet.size; // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
+

{{SpecName('ES6', '#sec-get-set.prototype.size', 'Set.prototype.size')}}

+
{{Spec2('ES6')}}初始定义
+

{{SpecName('ESDraft', '#sec-get-set.prototype.size', 'Set.prototype.size')}}

+
{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Set.size")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/set/values/index.html b/files/zh-cn/web/javascript/reference/global_objects/set/values/index.html new file mode 100644 index 0000000000..846bd7421d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/set/values/index.html @@ -0,0 +1,70 @@ +--- +title: Set.prototype.values() +slug: Web/JavaScript/Reference/Global_Objects/Set/values +tags: + - ECMAScript 2015 + - Iterator + - JavaScript + - Method + - Prototype + - set +translation_of: Web/JavaScript/Reference/Global_Objects/Set/values +--- +
{{JSRef}}
+ +

values() 方法按照元素插入顺序返回一个具有 Set 对象每个元素值的全新 Iterator 对象。

+ +

keys() 方法是这个方法的别名(与 {{jsxref("Map")}} 对象相似);他们的行为一致,都是返回Set 对象中的元素值。

+ +
{{EmbedInteractiveExample("pages/js/set-prototype-values.html")}}
+ + + +

语法

+ +
mySet.values();
+
+ +

返回值

+ +

按照元素插入顺序返回一个包含给定的 Set 对象中每个元素值的全新 Iterator 对象。

+ +

示例

+ +

使用 values()

+ +
var mySet = new Set();
+mySet.add('foo');
+mySet.add('bar');
+mySet.add('baz');
+
+var setIter = mySet.values();
+
+console.log(setIter.next().value); // "foo"
+console.log(setIter.next().value); // "bar"
+console.log(setIter.next().value); // "baz"
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-set.prototype.values', 'Set.prototype.values')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Set.values")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/bytelength/index.html b/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/bytelength/index.html new file mode 100644 index 0000000000..a558623014 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/bytelength/index.html @@ -0,0 +1,53 @@ +--- +title: SharedArrayBuffer.prototype.byteLength +slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/byteLength +tags: + - SharedArrayBuffer +translation_of: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/byteLength +--- +
{{JSRef}}
+ +

 byteLength 访问器属性表示以字节为单位的一个{{jsxref("SharedArrayBuffer")}}的长度。

+ +

语法

+ +
sab.byteLength
+ +

描述

+ +

byteLength属性是一个访问者属性,其set访问者函数为 undefined,这意味着您只能读取此属性。 该值在构造共享数组时建立,并且无法更改。

+ +

例子

+ +
var sab = new SharedArrayBuffer(1024);
+sab.byteLength; // 1024
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-get-sharedarraybuffer.prototype.bytelength', 'SharedArrayBuffer.prototype.byteLength')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.SharedArrayBuffer.byteLength")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/index.html b/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/index.html new file mode 100644 index 0000000000..93b5740def --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/index.html @@ -0,0 +1,144 @@ +--- +title: SharedArrayBuffer +slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer +tags: + - ArrayBuffer + - Service Worker + - Shared Memory + - SharedArrayBuffer + - TypedArrays + - Web Worker + - Worker + - 共享内存 + - 实验的 + - 构造函数 +translation_of: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer +--- +
{{JSRef}}
+ +

SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,类似于 {{jsxref("ArrayBuffer")}} 对象,它们都可以用来在共享内存(shared memory)上创建视图。与 ArrayBuffer 不同的是,SharedArrayBuffer 不能被分离。

+ +
+

请注意,作为对Spectre的响应,所有主流浏览器均默认于2018年1月5日禁用SharedArrayBuffer。 Chrome在启用了网站隔离功能的平台上的v67中重新启用了该功能,以防止出现Spectre风格的漏洞。

+
+ +

{{EmbedInteractiveExample("pages/js/sharedarraybuffer-constructor.html")}}

+ + + +

语法

+ +
new SharedArrayBuffer(length)
+
+ +

参数

+ +
+
length
+
所创建的数组缓冲区的大小,以字节(byte)为单位。
+
+ +

返回值

+ +

一个大小指定的新 SharedArrayBuffer 对象。其内容被初始化为 0。

+ +

描述

+ +

分配及共享内存

+ +

为了将一个{{jsxref("SharedArrayBuffer")}} 对象从一个用户代理共享到另一个用户代理(另一个页面的主进程或者当前页面的一个 worker )从而实现共享内存,我们需要运用 postMessage 和结构化克隆算法( structured cloning )。

+ +

结构化克隆算法接收被映射到一个新的 SharedArrayBuffers 对象上的 SharedArrayBuffers 对象与 TypedArrays 对象。在这两种映射下,这个新的 SharedArrayBuffer 对象会被传递到目标用户代理的接收函数上,导致在目标用户代理产生了一个新的私有 SharedArrayBuffer 对象(正如 {{jsxref("ArrayBuffer")}} 一样)。然而,这两个 SharedArrayBuffer 对象指向的共享数据块其实是同一个,并且在某一代理中的一个块的副作用将最终导致另一个代理具有可见性。

+ +
let sab = new SharedArrayBuffer(1024);
+worker.postMessage(sab);
+
+ +

通过原子操作更新及同步来共享内存

+ +

共享内存能被同时创建和更新于工作者线程或主线程。依赖于系统(CPU,操作系统,浏览器),变化传递给所有上下文环境需要一段时间。需要通过 {{jsxref("Atomics", "atomic", "", 1)}} 操作来进行同步。

+ +

接受 SharedArrayBuffer 对象的API

+ + + +

需要 new 运算符来构造

+ +

SharedArrayBuffer 需要 {{jsxref("Operators/new", "new")}} 运算符来构造一个构造函数. 作为函数来调用一个 SharedArrayBuffer 构造函数时,如果不用 new 运算符,将会抛出一个 {{jsxref("TypeError")}} 异常。

+ +
var sab = SharedArrayBuffer(1024);
+// TypeError: calling a builtin SharedArrayBuffer constructor
+// 必须用 new 来构造
+ +
var sab = new SharedArrayBuffer(1024);
+ +

属性

+ +
+
SharedArrayBuffer.length
+
SharedArrayBuffer 构造函数的 length 属性值为1。 
+
{{jsxref("SharedArrayBuffer.prototype")}}
+
允许所有 SharedArrayBuffer 对象的附加属性。
+
+ +

SharedArrayBuffer 原型对象

+ +

所有 SharedArrayBuffer 实例继承自 {{jsxref("SharedArrayBuffer.prototype")}}。

+ +

属性

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype','Properties')}}

+ +

方法

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype','Methods')}}

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-sharedarraybuffer-objects', 'SharedArrayBuffer')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
{{SpecName('ES8', '#sec-sharedarraybuffer-objects', 'SharedArrayBuffer')}}{{Spec2('ES8')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.SharedArrayBuffer")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html new file mode 100644 index 0000000000..ab4f881dff --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html @@ -0,0 +1,62 @@ +--- +title: SharedArrayBuffer.prototype +slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype +tags: + - Prototype + - SharedArrayBuffer +translation_of: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer +--- +
{{JSRef}}
+ +

SharedArrayBuffer.prototype  属性表示 {{jsxref("SharedArrayBuffer")}}  对象的原型。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

SharedArrayBuffer实例继承自SharedArrayBuffer.prototype。 与所有构造函数一样,您可以更改构造函数的原型对象以对所有SharedArrayBuffer实例进行更改。

+ +

属性

+ +
+
SharedArrayBuffer.prototype.constructor
+
指定创建对象原型的函数。 初始值为标准的内置SharedArrayBuffer构造函数。
+
{{jsxref("SharedArrayBuffer.prototype.byteLength")}} {{readonlyInline}}
+
数组的大小(以字节为单位)。 这是在数组初始化时建立的,并且无法被更改。 只读
+
+ +

方法

+ +
+
{{jsxref("SharedArrayBuffer.slice", "SharedArrayBuffer.prototype.slice(begin, end)")}}
+
返回一个新的SharedArrayBuffer,其内容是此SharedArrayBuffer字节从beigin开始(包括begin)到end结束(不包括end)的副本。 如果beginend为负,则它是指数组末尾的索引,而不是开头的索引。
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-sharedarraybuffer.prototype', 'SharedArrayBuffer.prototype')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.SharedArrayBuffer.prototype")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/slice/index.html b/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/slice/index.html new file mode 100644 index 0000000000..a13b9885f3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/slice/index.html @@ -0,0 +1,76 @@ +--- +title: SharedArrayBuffer.prototype.slice() +slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/slice +tags: + - SharedArrayBuffer + - slice +translation_of: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/slice +--- +
{{JSRef}}
+ +

SharedArrayBuffer.prototype.slice() 方法返回一个新的{{jsxref("SharedArrayBuffer")}} 副本,其内容是该SharedArrayBuffer的字节从begin开始(包含begin),直到end结束(不包含end)。如果beginend是负的,它指的是从数组末尾开始的索引。此方法与 {{jsxref("Array.prototype.slice()")}} 具有相同的算法。

+ +

{{EmbedInteractiveExample("pages/js/sharedarraybuffer-slice.html")}}

+ +

语法

+ +
sab.slice()
+sab.slice(begin)
+sab.slice(begin, end)
+ +

参数

+ +
+
begin {{optional_inline}}
+
从零开始的索引,从该索引开始提取。
+
可以使用一个负索引,表示从序列末尾开始的偏移量。 slice(-2)提取序列中的最后两个元素。
+
If begin is undefined, slice begins from index 0.如果begin为undefined,slice则从索引为0处开始。
+
end {{optional_inline}}
+
从零开始的索引,在此索引之前终止提取。 slice 执行提取到索引为end的位置(不包含end)。
+
例如,slice(1,4)提取第二个元素到第四个元素(索引为1、2和3的元素)。
+
可以使用一个负索引,表示从序列末尾开始的偏移量。 slice(2,-1)提取序列中从第三个元素开始,到倒数第二个元素结束的全部元素。
+
如果省略end,则slice一直提取到序列的末尾(sab.byteLength)。
+
+ +

返回值

+ +

一个包含被提取出的元素的新 {{jsxref("SharedArrayBuffer")}} 。

+ +

例子

+ +
var sab = new SharedArrayBuffer(1024);
+sab.slice();    // SharedArrayBuffer { byteLength: 1024 }
+sab.slice(2);   // SharedArrayBuffer { byteLength: 1022 }
+sab.slice(-2);  // SharedArrayBuffer { byteLength: 2 }
+sab.slice(0, 1); // SharedArrayBuffer { byteLength: 1 }
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-sharedarraybuffer.prototype.slice', 'SharedArrayBuffer.prototype.slice')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.SharedArrayBuffer.slice")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/@@iterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/@@iterator/index.html new file mode 100644 index 0000000000..8ea489430f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/@@iterator/index.html @@ -0,0 +1,137 @@ +--- +title: 'String.prototype[@@iterator]()' +slug: Web/JavaScript/Reference/Global_Objects/String/@@iterator +translation_of: Web/JavaScript/Reference/Global_Objects/String/@@iterator +--- +
{{JSRef}}
+ +

[@@iterator]() 方法返回一个新的Iterator对象,它遍历字符串的代码点,返回每一个代码点的字符串值。

+ +

{{EmbedInteractiveExample("pages/js/string-iterator.html")}}

+ +

The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

+ +

语法

+ +
string[Symbol.iterator]
+ +

返回值

+ +

一个新的Iterator对象。

+ +

示例

+ +

使用[@@iterator]()

+ +
var string = 'A\uD835\uDC68';
+
+var strIter = string[Symbol.iterator]();
+
+console.log(strIter.next().value); // "A"
+console.log(strIter.next().value); // "\uD835\uDC68"
+
+ +

通过 for..of 使用[@@iterator]()

+ +
var string = 'A\uD835\uDC68B\uD835\uDC69C\uD835\uDC6A';
+
+for (var v of string) {
+  console.log(v);
+}
+// "A"
+// "\uD835\uDC68"
+// "B"
+// "\uD835\uDC69"
+// "C"
+// "\uD835\uDC6A"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-string.prototype-@@iterator', 'String.prototype[@@iterator]()')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-string.prototype-@@iterator', 'String.prototype[@@iterator]()')}}{{Spec2('ESDraft')}}
+ + + + + + + +
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持{{CompatVersionUnknown}}{{CompatGeckoDesktop("36")}} [1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatNo}}{{CompatVersionUnknown}}{{CompatGeckoMobile("36")}} [1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] From Gecko 17 (Firefox 17 / Thunderbird 17 / SeaMonkey 2.14) to Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) the iterator property was used (bug 907077), and from Gecko 27 to Gecko 35 the "@@iterator" placeholder was used. In Gecko 36 (Firefox 36 / Thunderbird 36 / SeaMonkey 2.33), the @@iterator symbol got implemented (bug 918828).

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/anchor/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/anchor/index.html new file mode 100644 index 0000000000..0b3a4169cd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/anchor/index.html @@ -0,0 +1,136 @@ +--- +title: String.prototype.anchor() +slug: Web/JavaScript/Reference/Global_Objects/String/anchor +tags: + - HTML + - JavaScript + - Method + - Prototype + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/anchor +--- +
{{JSRef("Global_Objects", "String")}}
+ +

概述

+ +
+

已废弃
+ 该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。

+
+ +

anchor() 方法创建一个 {{HTMLElement("a")}} HTML 锚元素,被用作超文本靶标(hypertext target)。

+ +

语法

+ +
str.anchor(name) 
+ +

参数

+ +
+
name
+
一个字符串,表示被创建的标签的 name 属性。
+
+ +

返回值

+ +

 包含 {{HTMLElement("a")}} HTML元素的一个字符串。

+ +

描述

+ +

使用 anchor 方法能够以编程方式在一个文档中创建和展现一个锚链接。

+ +

语法上来讲,字符串表示你想让用户看到的文本。name 字符串参数表示 {{HTMLElement("a")}} 元素的 name 属性。

+ +

使用 anchor 方法创建的锚点(anchors)将会成为 {{domxref("document.anchors")}} 数组的元素。

+ +

示例

+ +

例子:使用 anchor

+ +
var myString = "Table of Contents";
+
+document.body.innerHTML = myString.anchor("contents_anchor");
+ +

将会输出下面的 HTML:

+ +
<a name="contents_anchor">Table of Contents</a>
+ +

规范

+ + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ES6', '#sec-string.prototype.anchor', 'String.prototype.anchor')}}{{Spec2('ES6')}}Initial definition. Implemented in JavaScript 1.0.
+ Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatGeckoDesktop("1.0") }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatGeckoMobile("1.0") }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Gecko-specific notes

+ +

从{{gecko("17")}}开始  " (引号) 被 HTML引用字符 &quot所替代;在字符串中申请命名参数.

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/big/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/big/index.html new file mode 100644 index 0000000000..8854fd3b2b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/big/index.html @@ -0,0 +1,123 @@ +--- +title: String.prototype.big() +slug: Web/JavaScript/Reference/Global_Objects/String/big +translation_of: Web/JavaScript/Reference/Global_Objects/String/big +--- +
{{JSRef}} {{deprecated_header}}
+ +

big()方法的作用是创建一个使字符串显示大号字体的{{HTMLElement("big")}}标签。

+ +
+

使用说明:  <big> 元素在HTML5中已经被移除了,不应该再使用它。 取而代之的是web开发人员应该使用CSS 属性。

+
+ +

语法

+ +
str.big()
+ +

返回值

+ +

带有 {{HTMLElement("big")}}标签的字符串。

+ +

描述

+ +

big() 方法会将一个字符串嵌入到<big>标签中: "<big>str</big>"。

+ +

示例

+ +

使用big()函数

+ +

下面的例子使用了字符串方法来改变一个字符串的字体大小:

+ +
var worldString = 'Hello, world';
+
+console.log(worldString.small());     // <small>Hello, world</small>
+console.log(worldString.big());       // <big>Hello, world</big>
+console.log(worldString.fontsize(7)); // <fontsize=7>Hello, world</fontsize>
+
+ +

使用 {{domxref("HTMLElement.style", "element.style")}} 对象,你能更加一般地获得和操作该元素的style属性,比如:

+ +
document.getElementById('yourElemId').style.fontSize = '2em';
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.big', 'String.prototype.big')}}{{Spec2('ES6')}}初始定义。 在JavaScript 1.0中实现。在(规范性)附件B中定义了用于Web浏览器的附加ECMAScript 特性。
{{SpecName('ESDraft', '#sec-string.prototype.big', 'String.prototype.big')}}{{Spec2('ESDraft')}}在(规范性)附件B中定义了用于Web浏览器的附加ECMAScript 特性。
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/blink/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/blink/index.html new file mode 100644 index 0000000000..88cdb9cbf8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/blink/index.html @@ -0,0 +1,119 @@ +--- +title: String.prototype.blink() +slug: Web/JavaScript/Reference/Global_Objects/String/blink +translation_of: Web/JavaScript/Reference/Global_Objects/String/blink +--- +
{{JSRef}} {{deprecated_header}}
+ +

blink()方法创建使字符串闪烁的 {{HTMLElement("blink")}} HTML 元素。

+ +
+

警告:闪烁文本被多种普及标准否决。 <blink>元素自身是非标准的,并且已废弃!

+
+ +

语法

+ +
str.blink()
+ +

返回值

+ +

包含  {{HTMLElement("blink")}} HTML 元素的字符串。

+ +

描述

+ +

blink()方法将字符串嵌入 <blink> 标签中: "<blink>str</blink>".

+ +

示例

+ +

使用blink()函数

+ +

下面的示例使用了字符串方法来修改字符串格式:

+ +
var worldString = 'Hello, world';
+
+console.log(worldString.blink());   // <blink>Hello, world</blink>
+console.log(worldString.bold());    // <b>Hello, world</b>
+console.log(worldString.italics()); // <i>Hello, world</i>
+console.log(worldString.strike());  // <strike>Hello, world</strike>
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.blink', 'String.prototype.blink')}}{{Spec2('ES6')}}初始定义。在 JavaScript 1.0 中实现。 在(规范性)附件 B 中定义了用于 Web 浏览器的 ECMAScript 附加特性。
{{SpecName('ESDraft', '#sec-string.prototype.blink', 'String.prototype.blink')}}{{Spec2('ESDraft')}}在(规范性)附件 B 中定义了用于 Web 浏览器的 ECMAScript 附加特性。
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/bold/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/bold/index.html new file mode 100644 index 0000000000..1ff02a8d34 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/bold/index.html @@ -0,0 +1,119 @@ +--- +title: String.prototype.bold() +slug: Web/JavaScript/Reference/Global_Objects/String/bold +tags: + - Deprecated + - HTML wrapper methods + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/String/bold +--- +

{{JSRef}} {{deprecated_header}}

+ +

bold() 方法会创建 HTML 元素 “b”,并将字符串加粗展示。

+ +

语法

+ +
str.bold()
+ +

返回值

+ +

包含HTML元素 {{HTMLElement("b")}} 的字符串。

+ +

描述

+ +

bold() 方法将一个字符串嵌入到<b></b>标记中。

+ +

示例

+ +

使用bold()

+ +

下面的例子使用字符串方法来改变字符串的格式。

+ +
var worldString = 'Hello, world';
+
+console.log(worldString.blink());   // <blink>Hello, world</blink>
+console.log(worldString.bold());    // <b>Hello, world</b>
+console.log(worldString.italics()); // <i>Hello, world</i>
+console.log(worldString.strike());  // <strike>Hello, world</strike>
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.bold', 'String.prototype.bold')}}{{Spec2('ES6')}}Initial definition. Implemented in JavaScript 1.0. Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
{{SpecName('ESDraft', '#sec-string.prototype.bold', 'String.prototype.bold')}}{{Spec2('ESDraft')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关连接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/charat/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/charat/index.html new file mode 100644 index 0000000000..3ed7dd0e7b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/charat/index.html @@ -0,0 +1,280 @@ +--- +title: String.prototype.charAt() +slug: Web/JavaScript/Reference/Global_Objects/String/charAt +tags: + - String.prototype.charAt() +translation_of: Web/JavaScript/Reference/Global_Objects/String/charAt +--- +

{{JSRef}}

+ +

概述

+ +

charAt() 方法从一个字符串中返回指定的字符。

+ +

语法

+ +
str.charAt(index)
+ +

参数

+ +
+
index
+
一个介于0 和字符串长度减1之间的整数。 (0~length-1)
+
如果没有提供索引,charAt() 将使用0。
+
 
+
+ +

描述

+ +

字符串中的字符从左向右索引,第一个字符的索引值为 0,最后一个字符(假设该字符位于字符串 stringName 中)的索引值为 stringName.length - 1。 如果指定的 index 值超出了该范围,则返回一个空字符串。

+ +

示例

+ +

例子:输出字符串中不同位置的字符

+ +

下例输出字符串 "Brave new world" 不同位置处的字符:

+ +
var anyString = "Brave new world";
+
+console.log("The character at index 0   is '" + anyString.charAt(0)   + "'");
+console.log("The character at index 1   is '" + anyString.charAt(1)   + "'");
+console.log("The character at index 2   is '" + anyString.charAt(2)   + "'");
+console.log("The character at index 3   is '" + anyString.charAt(3)   + "'");
+console.log("The character at index 4   is '" + anyString.charAt(4)   + "'");
+console.log("The character at index 999 is '" + anyString.charAt(999) + "'");
+
+ +

上面代码的输出为:

+ +
The character at index 0 is 'B'
+The character at index 1 is 'r'
+The character at index 2 is 'a'
+The character at index 3 is 'v'
+The character at index 4 is 'e'
+The character at index 999 is ''
+
+ +

例子:获取所有字符

+ +

以下提供了一种确保通过字符串循环总是提供整个字符的方法,即使该字符串包含不在基本多文种平面(BMP)中的字符。

+ +
var str = 'A \uD87E\uDC04 Z'; // We could also use a non-BMP character directly
+for (var i=0, chr; i < str.length; i++) {
+  if ((chr = getWholeChar(str, i)) === false) {
+    continue;
+  } // Adapt this line at the top of each loop, passing in the whole string and
+    // the current iteration and returning a variable to represent the
+    // individual character
+
+  alert(chr);
+}
+
+function getWholeChar (str, i) {
+  var code = str.charCodeAt(i);
+
+  if (isNaN(code)) {
+    return ''; // Position not found
+  }
+  if (code < 0xD800 || code > 0xDFFF) {
+    return str.charAt(i);
+  }
+
+  // High surrogate (could change last hex to 0xDB7F to treat high private
+  // surrogates as single characters)
+  if (0xD800 <= code && code <= 0xDBFF) {
+    if (str.length <= (i+1))  {
+      throw 'High surrogate without following low surrogate';
+    }
+    var next = str.charCodeAt(i+1);
+      if (0xDC00 > next || next > 0xDFFF) {
+        throw 'High surrogate without following low surrogate';
+      }
+      return str.charAt(i)+str.charAt(i+1);
+  }
+  // Low surrogate (0xDC00 <= code && code <= 0xDFFF)
+  if (i === 0) {
+    throw 'Low surrogate without preceding high surrogate';
+  }
+  var prev = str.charCodeAt(i-1);
+
+  // (could change last hex to 0xDB7F to treat high private
+  // surrogates as single characters)
+  if (0xD800 > prev || prev > 0xDBFF) {
+    throw 'Low surrogate without preceding high surrogate';
+  }
+  // We can pass over low surrogates now as the second component
+  // in a pair which we have already processed
+  return false;
+}
+
+
+ +

在允许解构分配的独占JavaScript 1.7+环境(如Firefox)中,以下是一个更简洁和更灵活的替代方法,它会自动递增一个递增变量(如果字符保证它是一个替代对)。

+ +
var str = 'A\uD87E\uDC04Z'; // We could also use a non-BMP character directly
+for (var i=0, chr; i < str.length; i++) {
+  [chr, i] = getWholeCharAndI(str, i);
+  // Adapt this line at the top of each loop, passing in the whole string and
+  // the current iteration and returning an array with the individual character
+  // and 'i' value (only changed if a surrogate pair)
+
+  alert(chr);
+}
+
+function getWholeCharAndI (str, i) {
+  var code = str.charCodeAt(i);
+
+  if (isNaN(code)) {
+    return ''; // Position not found
+  }
+  if (code < 0xD800 || code > 0xDFFF) {
+    return [str.charAt(i), i]; // Normal character, keeping 'i' the same
+  }
+
+  // High surrogate (could change last hex to 0xDB7F to treat high private
+  // surrogates as single characters)
+  if (0xD800 <= code && code <= 0xDBFF) {
+    if (str.length <= (i+1))  {
+      throw 'High surrogate without following low surrogate';
+    }
+    var next = str.charCodeAt(i+1);
+      if (0xDC00 > next || next > 0xDFFF) {
+        throw 'High surrogate without following low surrogate';
+      }
+      return [str.charAt(i)+str.charAt(i+1), i+1];
+  }
+  // Low surrogate (0xDC00 <= code && code <= 0xDFFF)
+  if (i === 0) {
+    throw 'Low surrogate without preceding high surrogate';
+  }
+  var prev = str.charCodeAt(i-1);
+
+  // (could change last hex to 0xDB7F to treat high private surrogates
+  // as single characters)
+  if (0xD800 > prev || prev > 0xDBFF) {
+    throw 'Low surrogate without preceding high surrogate';
+  }
+  // Return the next character instead (and increment)
+  return [str.charAt(i+1), i+1];
+}
+ +

示例:修复charAt以支持非基本多文种平面(BMP)字符

+ +

虽然上面的例子对于那些希望支持非BMP字符的用户可能更有用(因为它不要求调用者知道任何非BMP字符可能出现在哪里),在人们希望的情况下,在选择字符 通过索引,将字符串中的替代对作为它们表示的单个字符,可以使用以下:

+ +
function fixedCharAt (str, idx) {
+  var ret = '';
+  str += '';
+  var end = str.length;
+
+  var surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
+  while ((surrogatePairs.exec(str)) != null) {
+    var li = surrogatePairs.lastIndex;
+    if (li - 2 < idx) {
+      idx++;
+    } else {
+      break;
+    }
+  }
+
+  if (idx >= end || idx < 0) {
+    return '';
+  }
+
+  ret += str.charAt(idx);
+
+  if (/[\uD800-\uDBFF]/.test(ret) && /[\uDC00-\uDFFF]/.test(str.charAt(idx+1))) {
+    // Go one further, since one of the "characters" is part of a surrogate pair
+    ret += str.charAt(idx+1);
+  }
+  return ret;
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.5.4.4', 'String.prototype.charAt')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-string.prototype.charat', 'String.prototype.charAt')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/charcodeat/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/charcodeat/index.html new file mode 100644 index 0000000000..2fa6e19305 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/charcodeat/index.html @@ -0,0 +1,161 @@ +--- +title: String.prototype.charCodeAt() +slug: Web/JavaScript/Reference/Global_Objects/String/charCodeAt +tags: + - JavaScript + - String + - Unicode + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/charCodeAt +--- +
{{JSRef}}
+ +

charCodeAt() 方法返回 065535 之间的整数,表示给定索引处的 UTF-16 代码单元

+ +
{{EmbedInteractiveExample("pages/js/string-charcodeat.html", "shorter")}}
+ + + +

UTF-16 编码单元匹配能用一个 UTF-16 编码单元表示的 Unicode 码点。如果 Unicode 码点不能用一个 UTF-16 编码单元表示(因为它的值大于0xFFFF),则所返回的编码单元会是这个码点代理对的第一个编码单元) 。如果你想要整个码点的值,使用 {{jsxref("Global_Objects/String/codePointAt", "codePointAt()")}}。

+ +

语法

+ +
str.charCodeAt(index)
+ +

参数

+ +
+
index
+
一个大于等于 0,小于字符串长度的整数。如果不是一个数值,则默认为 0
+
+ +

返回值

+ +

指定 index 处字符的 UTF-16 代码单元值的一个数字;如果 index 超出范围,charCodeAt() 返回 {{jsxref("Global_Objects/NaN", "NaN")}}。

+ +

描述

+ +

Unicode 码点(code points)的范围从 01114111 (0x10FFFF)。开头的 128 个 Unicode 编码单元和 ASCII 字符编码一样。(关于 Unicode 的更多信息,可查看 JavaScript Guide。)

+ +
+

注意:charCodeAt 总是返回一个小于 65,536 的值。这是因为高位编码单元(higher code point)使用一对(低位编码 lower valued)代理伪字符("surrogate" pseudo-characters)来表示,从而构成一个真正的字符。

+ +

因此,为了检查(或重现)65536 及以上编码字符的完整字符,需要在获取 charCodeAt(i) 的值的同时获取 charCodeAt(i+1) 的值(如同用两个字母操纵一个字符串),或者改为获取 codePointAt(i) 的值。参看下面例 2 和例 3。

+
+ +

如果指定的 index 小于 0 、等于或大于字符串的长度,则 charCodeAt 返回 {{jsxref("Global_Objects/NaN", "NaN")}}。

+ +

向后兼容:在历史版本中(如 JavaScript 1.2),charCodeAt 返回一个数字,表示给定 index 处字符的 ISO-Latin-1 编码值。ISO-Latin-1 编码集范围从 0255。开头的 0127 直接匹配 ASCII 字符集。

+ +

示例

+ +

使用 charCodeAt()

+ +

下例介绍了不同索引情况下返回的 Unicode 值:

+ +
"ABC".charCodeAt(0) // returns 65:"A"
+
+"ABC".charCodeAt(1) // returns 66:"B"
+
+"ABC".charCodeAt(2) // returns 67:"C"
+
+"ABC".charCodeAt(3) // returns NaN
+ +

使用 charCodeAt() 修复字符串中出现的未知的非基本多语言范围(非BMP,non-Basic-Multilingual-Plane)字符

+ +

这段代码可以被用在 for 循环和其他类似语句中,当在指定引索之前不确定是否有非BMP字符存在时。

+ +
function fixedCharCodeAt (str, idx) {
+    // ex. fixedCharCodeAt ('\uD800\uDC00', 0); // 65536
+    // ex. fixedCharCodeAt ('\uD800\uDC00', 1); // false
+    idx = idx || 0;
+    var code = str.charCodeAt(idx);
+    var hi, low;
+
+    // High surrogate (could change last hex to 0xDB7F to treat high
+    // private surrogates as single characters)
+    if (0xD800 <= code && code <= 0xDBFF) {
+        hi = code;
+        low = str.charCodeAt(idx+1);
+        if (isNaN(low)) {
+            throw 'High surrogate not followed by low surrogate in fixedCharCodeAt()';
+        }
+        return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
+    }
+    if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
+        // We return false to allow loops to skip this iteration since should have
+        // already handled high surrogate above in the previous iteration
+        return false;
+        /*hi = str.charCodeAt(idx-1);
+        low = code;
+        return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;*/
+    }
+    return code;
+}
+
+ +

使用 charCodeAt() 修复字符串中出现的已知的非BMP字符

+ +
function knownCharCodeAt (str, idx) {
+    str += '';
+    var code,
+        end = str.length;
+
+    var surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
+    while ((surrogatePairs.exec(str)) != null) {
+        var li = surrogatePairs.lastIndex;
+        if (li - 2 < idx) {
+            idx++;
+        }
+        else {
+            break;
+        }
+    }
+
+    if (idx >= end || idx < 0) {
+        return NaN;
+    }
+
+    code = str.charCodeAt(idx);
+
+    var hi, low;
+    if (0xD800 <= code && code <= 0xDBFF) {
+        hi = code;
+        low = str.charCodeAt(idx+1);
+        // Go one further, since one of the "characters" is part of a surrogate pair
+        return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
+    }
+    return code;
+}
+
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-string.prototype.charcodeat', 'String.prototype.charCodeAt')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.charCodeAt")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/codepointat/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/codepointat/index.html new file mode 100644 index 0000000000..567de8abc1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/codepointat/index.html @@ -0,0 +1,173 @@ +--- +title: String.prototype.codePointAt() +slug: Web/JavaScript/Reference/Global_Objects/String/codePointAt +translation_of: Web/JavaScript/Reference/Global_Objects/String/codePointAt +--- +
{{JSRef}}
+ +

codePointAt() 方法返回 一个 Unicode 编码点值的非负整数。

+ +

语法

+ +
str.codePointAt(pos)
+ +

参数

+ +
+
pos
+
这个字符串中需要转码的元素的位置。
+
+ +

返回值

+ +

返回值是在字符串中的给定索引的编码单元体现的数字,如果在索引处没找到元素则返回 {{jsxref("undefined")}} 。

+ +

描述

+ +

如果在指定的位置没有元素则返回 {{jsxref("undefined")}} 。如果在索引处开始没有UTF-16 代理对,将直接返回在那个索引处的编码单元。

+ +

Surrogate Pair是UTF-16中用于扩展字符而使用的编码方式,是一种采用四个字节(两个UTF-16编码)来表示一个字符,称作代理对。

+ +

例子

+ +

使用 codePointAt()

+ +
'ABC'.codePointAt(1);          // 66
+'\uD800\uDC00'.codePointAt(0); // 65536
+
+'XYZ'.codePointAt(42); // undefined
+
+ +

替补支持(Polyfill)

+ +

给原生不支持 ECMAScript 6 的浏览器使用codePointAt()方法的的一个字符串扩展方法。

+ +
/*! http://mths.be/codepointat v0.1.0 by @mathias */
+if (!String.prototype.codePointAt) {
+  (function() {
+    'use strict'; // 严格模式,needed to support `apply`/`call` with `undefined`/`null`
+    var codePointAt = function(position) {
+      if (this == null) {
+        throw TypeError();
+      }
+      var string = String(this);
+      var size = string.length;
+      // 变成整数
+      var index = position ? Number(position) : 0;
+      if (index != index) { // better `isNaN`
+        index = 0;
+      }
+      // 边界
+      if (index < 0 || index >= size) {
+        return undefined;
+      }
+      // 第一个编码单元
+      var first = string.charCodeAt(index);
+      var second;
+      if ( // 检查是否开始 surrogate pair
+        first >= 0xD800 && first <= 0xDBFF && // high surrogate
+        size > index + 1 // 下一个编码单元
+      ) {
+        second = string.charCodeAt(index + 1);
+        if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
+          // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+          return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+        }
+      }
+      return first;
+    };
+    if (Object.defineProperty) {
+      Object.defineProperty(String.prototype, 'codePointAt', {
+        'value': codePointAt,
+        'configurable': true,
+        'writable': true
+      });
+    } else {
+      String.prototype.codePointAt = codePointAt;
+    }
+  }());
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.codepointat', 'String.prototype.codePointAt')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-string.prototype.codepointat', 'String.prototype.codePointAt')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持{{CompatChrome("41")}}{{CompatGeckoDesktop("29")}}11{{CompatOpera("28")}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("29")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/concat/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/concat/index.html new file mode 100644 index 0000000000..ee2d8dd06d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/concat/index.html @@ -0,0 +1,83 @@ +--- +title: String.prototype.concat() +slug: Web/JavaScript/Reference/Global_Objects/String/concat +tags: + - JavaScript + - Method + - Prototype + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/concat +--- +
{{JSRef}}
+ +

concat() 方法将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回。

+ +

语法

+ +
str.concat(str2, [, ...strN])
+ +

参数

+ +
+
str2 [, ...strN]
+
需要连接到 str 的字符串。
+
+ +

返回值

+ +

一个新的字符串,包含参数所提供的连接字符串。

+ +

描述

+ +

concat 方法将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回。 concat 方法并不影响原字符串。

+ +

如果参数不是字符串类型,它们在连接之前将会被转换成字符串。

+ +

性能

+ +

强烈建议使用赋值操作符+, +=)代替 concat 方法。

+ +

示例

+ +

使用 concat

+ +

下面的例子演示如何将多个字符串与原字符串合并为一个新字符串

+ +
let hello = 'Hello, '
+console.log(hello.concat('Kevin', '. Have a nice day.'))
+// Hello, Kevin. Have a nice day.
+
+let greetList = ['Hello', ' ', 'Venkat', '!']
+"".concat(...greetList)  // "Hello Venkat!"
+
+"".concat({})    // [object Object]
+"".concat([])    // ""
+"".concat(null)  // "null"
+"".concat(true)  // "true"
+"".concat(4, 5)  // "45"
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-string.prototype.concat', 'String.prototype.concat')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.String.concat")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/endswith/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/endswith/index.html new file mode 100644 index 0000000000..f7ed81e221 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/endswith/index.html @@ -0,0 +1,98 @@ +--- +title: String.prototype.endsWith() +slug: Web/JavaScript/Reference/Global_Objects/String/endsWith +tags: + - JavaScript + - Method + - Prototype + - Reference + - String + - 原型 + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/endsWith +--- +

{{JSRef}}

+ +

endsWith()方法用来判断当前字符串是否是以另外一个给定的子字符串“结尾”的,根据判断结果返回 truefalse

+ +
{{EmbedInteractiveExample("pages/js/string-endswith.html")}}
+ + + +

语法

+ +
str.endsWith(searchString[, length])
+ +

参数

+ +
+
searchString
+
要搜索的子字符串。
+
length {{optional_inline}}
+
作为 str 的长度。默认值为 str.length
+
+ +

返回值

+ +

如果传入的子字符串在搜索字符串的末尾则返回true;否则将返回 false

+ +

描述

+ +

这个方法帮助你确定一个字符串是否在另一个字符串的末尾。这个方法是大小写敏感的。

+ +

Polyfill

+ +

这个方法已经加入到 ECMAScript 6 标准当中,但是可能还没有在所有的  JavaScript 实现中可用。然而,你可以通过如下的代码片段扩展 String.prototype.endsWith() 实现兼容:

+ +
if (!String.prototype.endsWith) {
+	String.prototype.endsWith = function(search, this_len) {
+		if (this_len === undefined || this_len > this.length) {
+			this_len = this.length;
+		}
+		return this.substring(this_len - search.length, this_len) === search;
+	};
+}
+
+ +

示例

+ +

使用 endsWith()

+ +
var str = "To be, or not to be, that is the question.";
+
+alert( str.endsWith("question.") );  // true
+alert( str.endsWith("to be") );      // false
+alert( str.endsWith("to be", 19) );  // true
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-string.prototype.endswith', 'String.prototype.endsWith')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.endsWith")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/fixed/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/fixed/index.html new file mode 100644 index 0000000000..f4af9c1103 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/fixed/index.html @@ -0,0 +1,117 @@ +--- +title: String.prototype.fixed() +slug: Web/JavaScript/Reference/Global_Objects/String/fixed +tags: + - Deprecated + - HTML wrapper methods + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/String/fixed +--- +
{{JSRef}} {{deprecated_header}}
+ +

fixed()方法创建了一个<tt>标签元素将字符串包裹起来,从而让这个字符串里面的内容具有固定间距。

+ +

语法

+ +
str.fixed()
+
+ +

Return value

+ +

返回一个表示 {{HTMLElement("tt")}} HTML 元素的字符串。

+ +

描述

+ +

fixed() 方法将一个字符串包裹在<tt></tt>标签中,比如: "<tt>str</tt>".

+ +

举例

+ +

使用fixed()

+ +

下面的示例代码使用这个fixed方法来改变字符串的格式:

+ +
var worldString = 'Hello, world';
+console.log(worldString.fixed()); // "<tt>Hello, world</tt>"
+
+ +

说明

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.fixed', 'String.prototype.fixed')}}{{Spec2('ES6')}}Initial definition. Implemented in JavaScript 1.0. Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
{{SpecName('ESDraft', '#sec-string.prototype.fixed', 'String.prototype.fixed')}}{{Spec2('ESDraft')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
版本ChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
版本AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/fontcolor/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/fontcolor/index.html new file mode 100644 index 0000000000..1f9775194a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/fontcolor/index.html @@ -0,0 +1,141 @@ +--- +title: String.prototype.fontcolor() +slug: Web/JavaScript/Reference/Global_Objects/String/fontcolor +tags: + - Deprecated + - HTML wrapper methods + - JavaScript + - Method + - Prototype + - Reference + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/fontcolor +--- +
{{JSRef}} {{deprecated_header}}
+ +

fontcolor()方法创建一个{{HTMLElement("font")}}的HTML元素让字符串被显示成指定的字体颜色。

+ +
+

使用注意:<font>元素已经在在HTML5中被移除并且不应该在使用。替代的是,web开发者应该使用CSS属性。

+
+ +

语法

+ +
str.fontcolor(color)
+ +

参数

+ +
+
color
+
代表颜色的一个字符串,可以是三个一组的十六进制的RGB值,也可以是一个颜色名称的字符串字面量,颜色名称的字符串字面量被列在了这里CSS颜色参考
+
+ +

返回值

+ +
+
一个包含一个{{HTMLElement("font")}} HTML元素的字符串。
+
+ +

描述

+ +

如果你表示的颜色为十六进制RGB三原色,则必须使用的格式rrggbb例如,对于橙红色的十六进制RGB值是红色=FA,绿色=80,和蓝=72,所以橙红色的RGB三原色"FA8072"

+ +

例子

+ +

使用 fontcolor()

+ +

下面的示例使用fontcolor()方法来改变字符串的颜色,通过产生一个被HTML <font> 标签包裹的字符串

+ +
var worldString = "Hello, world"
+
+console.log(worldString.fontcolor('red') + ' is red in this line');
+// <font color="red">Hello, world </font> is red in this line"
+
+console.log(worldString.fontcolor('FF00') + ' is red in hexadecimal'
+// <font color="FF00">Hello,world </font> is red in hexadecimal
+
+ +

和{{domxref("HTMLElement.style","element.style")}}对象一起,你可以访问元素的style属性,并且更随意的去操纵它,例如:

+ +
document.getElementById('yourElemId').style.color ='red';
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
规范状态评论
{{SpecName('ES6','#string.prototype.fontcolor', 'String.prototype.fontcolor')}}{{Spec2('ES6')}}初始定义。实现在JavaScript中1.0。定义为附加功能的ECMAScript针对Web浏览器(规范)附件B。
{{SpecName('ESDraft', '#string.prototype.fontcolor', 'String.prototype.fontcolor')}}{{Spec2('ESDraft')}}定义为附加功能的ECMAScript针对Web浏览器(规范)附件B。
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox(Gecko)Internet ExplorerOperaSafari
Basic Support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile(Gecko)IE MobileOpera MobileSafari Mobile
Basic Support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

也可以看看

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/fontsize/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/fontsize/index.html new file mode 100644 index 0000000000..676e1eff43 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/fontsize/index.html @@ -0,0 +1,130 @@ +--- +title: String.prototype.fontsize() +slug: Web/JavaScript/Reference/Global_Objects/String/fontsize +translation_of: Web/JavaScript/Reference/Global_Objects/String/fontsize +--- +
{{JSRef}} {{deprecated_header}}
+ +

The fontsize() method creates a {{HTMLElement("font")}} HTML element that causes a string to be displayed in the specified font size.

+ +
+

Usage note: The <font> element has been removed in HTML5 and shouldn't be used anymore. Instead web developers should use CSS properties.

+
+ +

语法

+ +
str.fontsize(size)
+ +

参数

+ +
+
size
+
An integer between 1 and 7, a string representing a signed integer between 1 and 7.
+
+ +

返回值

+ +

A string containing a {{HTMLElement("font")}} HTML element.

+ +

描述

+ +

When you specify size as an integer, you set the font size of str to one of the 7 defined sizes. When you specify size as a string such as "-2", you adjust the font size of str relative to the size set in the {{HTMLElement("basefont")}} tag.

+ +

示例

+ +

使用fontsize()方法

+ +

The following example uses string methods to change the size of a string:

+ +
var worldString = 'Hello, world';
+
+console.log(worldString.small());     // <small>Hello, world</small>
+console.log(worldString.big());       // <big>Hello, world</big>
+console.log(worldString.fontsize(7)); // <font size="7">Hello, world</fontsize>
+
+ +

With the {{domxref("HTMLElement.style", "element.style")}} object you can get the element's style attribute and manipulate it more generically, for example:

+ +
document.getElementById('yourElemId').style.fontSize = '0.7em';
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.fontsize', 'String.prototype.fontsize')}}{{Spec2('ES6')}}Initial definition. Implemented in JavaScript 1.0. Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
{{SpecName('ESDraft', '#sec-string.prototype.fontsize', 'String.prototype.fontsize')}}{{Spec2('ESDraft')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/fromcharcode/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/fromcharcode/index.html new file mode 100644 index 0000000000..fd399adab7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/fromcharcode/index.html @@ -0,0 +1,91 @@ +--- +title: String.fromCharCode() +slug: Web/JavaScript/Reference/Global_Objects/String/fromCharCode +tags: + - ASCII码变成字符串 + - fromCharCode +translation_of: Web/JavaScript/Reference/Global_Objects/String/fromCharCode +--- +

{{JSRef}}

+ +

静态 String.fromCharCode() 方法返回由指定的 UTF-16 代码单元序列创建的字符串。

+ +
{{EmbedInteractiveExample("pages/js/string-fromcharcode.html")}}
+ + + +

语法

+ +
String.fromCharCode(num1[, ...[, numN]])
+ +

参数

+ +
+
num1, ..., numN
+
一系列 UTF-16 代码单元的数字。范围介于 0655350xFFFF)之间。大于 0xFFFF 的数字将被截断。不进行有效性检查。
+
+ +

返回值

+ +

一个长度为 N 的字符串,由 N 个指定的 UTF-16 代码单元组成。

+ +

描述

+ +

该方法返回一个字符串,而不是一个  {{jsxref("String")}} 对象。

+ +

由于 fromCharCode() 是  {{jsxref("String")}} 的静态方法,所以应该像这样使用:String.fromCharCode(),而不是作为你创建的  {{jsxref("String")}} 对象的方法。

+ +

返回补充字符

+ +

在 UTF-16 中,绝大部分常用的字符可以用一个 16 位的值表示(即一个代码单元)。然而,有一类字符叫 Base Multilingual Plane (BMP),是所有可寻址的 Unicode 码点的 1/17th。剩下的码点,从范围 65536 (0x010000) 到 1114111 (0x10FFFF) 被称之为补充字符。在 UTF-16 中,补充字符也叫代理(surrogates),用两个 16 位代码单元表示,它是有目的被保留下来的。两个代理(surrogates)形成一个有效组合,也叫代理对,可以用来表示一个补充字符。

+ +

因为 fromCharCode() 只作用于 16 位的值 (跟 \u 转义序列一样),为了返回一个补充字符,一个代理对是必须的。例如,String.fromCharCode(0xD83C, 0xDF03)\uD83C\uDF03 返回码点 U+1F303 "Night with Stars"。

+ +

While there is a mathematical relationship between the supplementary code point value (e.g. 0x1F303) and both surrogate values that represent it (e.g., 0xD83C and 0xDF03), it does require an extra step to either calculate or look up the surrogate pair values every time a supplementary code point is to be used. 因此,使用 {{jsxref("String.fromCodePoint()")}} (ES2015 标准下的一个方法)更方便, 这个方法允许你基于真实的码点返回补充字符。例如 String.fromCodePoint(0x1F303) 返回码点 U+1F303 "Night with Stars"。

+ +

示例

+ +

使用 fromCharCode()

+ +

在 UTF-16 中,BMP 字符使用一个代码单元:

+ +
String.fromCharCode(65, 66, 67);   // 返回 "ABC"
+String.fromCharCode(0x2014);       // 返回 "—"
+String.fromCharCode(0x12014);      // 也是返回 "—"; 数字 1 被剔除并忽略
+String.fromCharCode(8212);         // 也是返回 "—"; 8212 是 0x2014 的十进制表示
+
+ +

完整的 UTF 16 表格.
+ 在 UTF-16 中,补充字符需要两个代码单元(即一个代理对):

+ +
String.fromCharCode(0xD83C, 0xDF03); // Code Point U+1F303 "Night with
+String.fromCharCode(55356, 57091);   // Stars" == "\uD83C\uDF03"
+
+String.fromCharCode(0xD834, 0xDF06, 0x61, 0xD834, 0xDF07); // "\uD834\uDF06a\uD834\uDF07"
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-string.fromcharcode', 'String.fromCharCode')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.String.fromCharCode")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/fromcodepoint/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/fromcodepoint/index.html new file mode 100644 index 0000000000..786125e340 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/fromcodepoint/index.html @@ -0,0 +1,144 @@ +--- +title: String.fromCodePoint() +slug: Web/JavaScript/Reference/Global_Objects/String/fromCodePoint +translation_of: Web/JavaScript/Reference/Global_Objects/String/fromCodePoint +--- +
{{JSRef}}
+ +

String.fromCodePoint() 静态方法返回使用指定的代码点序列创建的字符串。

+ +
{{EmbedInteractiveExample("pages/js/string-fromcodepoint.html")}}
+ + + +

语法

+ +
String.fromCodePoint(num1[, ...[, numN]])
+ +

参数

+ +
+
num1, ..., numN
+
一串 Unicode 编码位置,即“代码点”。
+
+

返回值

+ +

使用指定的 Unicode 编码位置创建的字符串。

+
+
+ +

异常

+ +
+
{{jsxref("RangeError")}}
+
如果传入无效的 Unicode 编码,将会抛出一个{{jsxref("RangeError")}} (例如: "RangeError: NaN is not a valid code point")。
+
+ +

说明

+ +

该方法返回一个字符串,而不是一个 {{jsxref("String")}} 对象。

+ +

因为 fromCodePoint() 是 {{jsxref("String")}} 的一个静态方法,所以只能通过 String.fromCodePoint() 这样的方式来使用,不能在你创建的 {{jsxref("String")}} 对象实例上直接调用。

+ +

例子

+ +

使用 fromCodePoint()

+ +
String.fromCodePoint(42);       // "*"
+String.fromCodePoint(65, 90);   // "AZ"
+String.fromCodePoint(0x404);    // "\u0404"
+String.fromCodePoint(0x2F804);  // "\uD87E\uDC04"
+String.fromCodePoint(194564);   // "\uD87E\uDC04"
+String.fromCodePoint(0x1D306, 0x61, 0x1D307) // "\uD834\uDF06a\uD834\uDF07"
+
+String.fromCodePoint('_');      // RangeError
+String.fromCodePoint(Infinity); // RangeError
+String.fromCodePoint(-1);       // RangeError
+String.fromCodePoint(3.14);     // RangeError
+String.fromCodePoint(3e-2);     // RangeError
+String.fromCodePoint(NaN);      // RangeError
+
+ +
// String.fromCharCode() 方法不能单独获取在高代码点位上的字符
+// 另一方面,下列的示例中,可以返回 4 字节,也可以返回 2 字节的字符
+// (也就是说,它可以返回单独的字符,使用长度 2 代替 1!)
+console.log(String.fromCodePoint(0x2F804)); // or 194564 in decimal
+
+ +

Polyfill

+ +

String.fromCodePoint 方法是 ECMAScript2015(ES6)新增加的特性,所以一些老的浏览器可能还不支持。可以通过使用下面的 polyfill 代码来保证浏览器的支持:

+ +
if (!String.fromCodePoint) (function(stringFromCharCode) {
+    var fromCodePoint = function(_) {
+      var codeUnits = [], codeLen = 0, result = "";
+      for (var index=0, len = arguments.length; index !== len; ++index) {
+        var codePoint = +arguments[index];
+        // correctly handles all cases including `NaN`, `-Infinity`, `+Infinity`
+        // The surrounding `!(...)` is required to correctly handle `NaN` cases
+        // The (codePoint>>>0) === codePoint clause handles decimals and negatives
+        if (!(codePoint < 0x10FFFF && (codePoint>>>0) === codePoint))
+          throw RangeError("Invalid code point: " + codePoint);
+        if (codePoint <= 0xFFFF) { // BMP code point
+          codeLen = codeUnits.push(codePoint);
+        } else { // Astral code point; split in surrogate halves
+          // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+          codePoint -= 0x10000;
+          codeLen = codeUnits.push(
+            (codePoint >> 10) + 0xD800,  // highSurrogate
+            (codePoint % 0x400) + 0xDC00 // lowSurrogate
+          );
+        }
+        if (codeLen >= 0x3fff) {
+          result += stringFromCharCode.apply(null, codeUnits);
+          codeUnits.length = 0;
+        }
+      }
+      return result + stringFromCharCode.apply(null, codeUnits);
+    };
+    try { // IE 8 only supports `Object.defineProperty` on DOM elements
+      Object.defineProperty(String, "fromCodePoint", {
+        "value": fromCodePoint, "configurable": true, "writable": true
+      });
+    } catch(e) {
+      String.fromCodePoint = fromCodePoint;
+    }
+}(String.fromCharCode));
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-string.fromcodepoint', 'String.fromCodePoint')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-string.fromcodepoint', 'String.fromCodePoint')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.fromCodePoint")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/includes/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/includes/index.html new file mode 100644 index 0000000000..83ced4b38a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/includes/index.html @@ -0,0 +1,111 @@ +--- +title: String.prototype.includes() +slug: Web/JavaScript/Reference/Global_Objects/String/includes +tags: + - JavaScript + - Method + - Monkey patching + - Prototype + - String + - String.prototype.includes() +translation_of: Web/JavaScript/Reference/Global_Objects/String/includes +--- +
{{JSRef}}
+ +

includes() 方法用于判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false。

+ +

语法

+ +
str.includes(searchString[, position])
+ +

参数

+ +
+
searchString
+
要在此字符串中搜索的字符串。
+
position {{optional_inline}}
+
从当前字符串的哪个索引位置开始搜寻子字符串,默认值为 0
+
+

返回值

+
+
如果当前字符串包含被搜寻的字符串,就返回 true;否则返回 false
+
+ +

描述

+ +

这个方法可以帮你判断一个字符串是否包含另外一个字符串。

+ +

区分大小写

+ +

includes() 方法是区分大小写的。例如,下面的表达式会返回 false

+ +
'Blue Whale'.includes('blue'); // returns false
+ +

兼容补丁

+ +

这个方法已经被加入到 ECMAScript 6 标准中,但未必在所有的 JavaScript 实现中都可以使用。然而,你可以轻松地 polyfill 这个方法:

+ +
if (!String.prototype.includes) {
+  String.prototype.includes = function(search, start) {
+    'use strict';
+    if (typeof start !== 'number') {
+      start = 0;
+    }
+
+    if (start + search.length > this.length) {
+      return false;
+    } else {
+      return this.indexOf(search, start) !== -1;
+    }
+  };
+}
+ +

示例

+ +

使用 includes()

+ +
var str = 'To be, or not to be, that is the question.';
+
+console.log(str.includes('To be'));       // true
+console.log(str.includes('question'));    // true
+console.log(str.includes('nonexistent')); // false
+console.log(str.includes('To be', 1));    // false
+console.log(str.includes('TO BE'));       // false
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-string.prototype.includes', 'String.prototype.includes')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.String.includes")}}

+ +

String.prototype.contains()

+ +

在 Firefox 18 - 39中,这个方法的名称叫 contains()。由于下面的理由,在{{bug(1102219)}}中,它被重命名为 includes() :

+ +

据报道,在Firefox 17上,一些使用 MooTools 1.2的网站会崩溃掉。这个版本的MooTools会检查函数 String.prototype.contains()  是否存在,如果不存在的话,MooTools就添加它自己的函数。通过在Firefox 17中引入这个函数,检查更改的行为在一定程度上导致了基于MooTools的 String.prototype.contains() 函数的代码实现中断。结果是,当 MooTools的拓展 导致 MooTools 1.2.6 版本的发布,此实现在Firefox 17中不可用和 String.prototype.contains() 在随后一个版本Firefox 18上是可用的。

+ +

MooTools 1.3会强制使用它自己版本的函数 String.prototype.contains(),因此,依赖它的网站不会崩溃掉。然而,你应该注意此方法在 MooTools 1.3 签名和ECMAScript 6 签名中的不同(在第二个参数)。后来,为了与ES6标准一致在MooTools 1.5版本及以上更改了签名

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/index.html new file mode 100644 index 0000000000..d8b23c0904 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/index.html @@ -0,0 +1,357 @@ +--- +title: String +slug: Web/JavaScript/Reference/Global_Objects/String +tags: + - JavaScript + - String + - 参考 + - 字符串 +translation_of: Web/JavaScript/Reference/Global_Objects/String +--- +
{{JSRef}}
+ +

String 全局对象是一个用于字符串或一个字符序列的构造函数。

+ +

语法

+ +

字符串字面量采取以下形式:

+ +
'string text'
+"string text"
+"中文/汉语"
+"español"
+"English "
+"हिन्दी"
+"العربية"
+"português"
+"বাংলা"
+"русский"
+"日本語"
+"ਪੰਜਾਬੀ"
+"한국어"
+ +

你也能使用 String 函数将其他值生成或转换成字符串:

+ +
String(thing)
+new String(thing)
+ +

参数

+ +
+
thing
+
任何可以被转换成字符串的值。
+
+ +

模板字面量

+ +

从 ECMAScript 2015 开始,字符串字面量也可以称为模板字面量

+ +
`hello world` `hello! world!` `hello ${who}` escape `<a>${who}</a>`
+ +

转义字符

+ +
+
+ +

除了普通的可打印字符以外,一些有特殊功能的字符可以通过转义字符的形式放入字符串中:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CodeOutput
\0空字符
\'单引号
\"双引号
\\反斜杠
\n换行
\r回车
\v垂直制表符
\t水平制表符
\b退格
\f换页
\uXXXXunicode 码
\u{X} ... \u{XXXXXX}unicode codepoint {{experimental_inline}}
\xXXLatin-1 字符(x小写)
+ +
和其他语言不同,javascript 的字符串不区分单引号和双引号,所以不论是单引号还是双引号的字符串,上面的转义字符都能运行 。
+ +

长字符串

+ +

有时,你的代码可能含有很长的字符串。你可能想将这样的字符串写成多行,而不是让这一行无限延长或着被编辑器折叠。有两种方法可以做到这一点。

+ +

其一,可以使用 + 运算符将多个字符串连接起来,如下所示:

+ +
let longString = "This is a very long string which needs " +
+                 "to wrap across multiple lines because " +
+                 "otherwise my code is unreadable.";
+ +

其二,可以在每行末尾使用反斜杠字符(“\”),以指示字符串将在下一行继续。确保反斜杠后面没有空格或任何除换行符之外的字符或缩进; 否则反斜杠将不会工作。 如下所示:

+ +
let longString = "This is a very long string which needs \
+to wrap across multiple lines because \
+otherwise my code is unreadable.";
+ +

使用这两种方式会创建相同的字符串。

+ +
+
+ +

描述

+ +

字符串对于保存可以以文本形式表示的数据非常有用。 一些常用的字符串操作有:查询字符串长度,使用 + 和 += 运算符来构建和连接字符串,使用 indexOf 方法检查某一子字符串在父字符串中的位置,又或是使用 substring 方法提取从父字符串中提取子字符串。

+ +

从字符串中获取单个字符

+ +

获取字符串的某个字符有两种方法。 第一种是使用 {{jsxref("String.charAt", "charAt")}} 方法:

+ +
return 'cat'.charAt(1); // returns "a"
+
+ +

另一种 (在ECMAScript 5中有所介绍) 是把字符串当作一个类似数组的对象,其中的每个字符对应一个数值索引:

+ +
return 'cat'[1]; // returns "a"
+
+ +

使用括号访问字符串不可以对其进行删除或添加,因为字符串对应未知的属性并不是可读或配置的。 (更多的信息请参阅 {{jsxref("Object.defineProperty")}}。 )

+ +

字符串比较

+ +

熟练使用 C 语言的开发者经常使用 strcmp 函数来比较字符串,但在 JavaScript 中,你只需要使用比较操作符(>/</>=/<=)

+ +
var a = "a";
+var b = "b";
+if (a < b) // true
+  print(a + " is less than " + b);
+else if (a > b)
+  print(a + " is greater than " + b);
+else
+  print(a + " and " + b + " are equal.");
+
+ +

使用从字符串实例继承而来的 {{jsxref("String.localeCompare", "localeCompare")}} 方法也能达到同样的效果。 

+ +

基本字符串和字符串对象的区别

+ +

请注意区分 JavaScript 字符串对象和基本字符串值 . ( 对于 {{jsxref("Global_Objects/Boolean", "Boolean")}} 和{{jsxref("Global_Objects/Number", "Numbers")}} 也同样如此.)

+ +

字符串字面量 (通过单引号或双引号定义) 和 直接调用 String 方法(没有通过 new 生成字符串对象实例)的字符串都是基本字符串。JavaScript会自动将基本字符串转换为字符串对象,只有将基本字符串转化为字符串对象之后才可以使用字符串对象的方法。当基本字符串需要调用一个字符串对象才有的方法或者查询值的时候(基本字符串是没有这些方法的),JavaScript 会自动将基本字符串转化为字符串对象并且调用相应的方法或者执行查询。

+ +
var s_prim = "foo";
+var s_obj = new String(s_prim);
+
+console.log(typeof s_prim); // Logs "string"
+console.log(typeof s_obj);  // Logs "object"
+
+ +

当使用 {{jsxref("Global_Objects/eval", "eval")}}时,基本字符串和字符串对象也会产生不同的结果。eval 会将基本字符串作为源代码处理; 而字符串对象则被看作对象处理, 返回对象。 例如:

+ +
s1 = "2 + 2";               // creates a string primitive
+s2 = new String("2 + 2");   // creates a String object
+console.log(eval(s1));      // returns the number 4
+console.log(eval(s2));      // returns the string "2 + 2"
+
+ +

由于上述原因, 当一段代码在需要使用基本字符串的时候却使用了字符串对象就会导致执行失败(虽然一般情况下程序员们并不需要考虑这样的问题)。

+ +

利用 {{jsxref("String.valueOf", "valueOf")}} 方法,我们可以将字符串对象转换为其对应的基本字符串。

+ +
console.log(eval(s2.valueOf())); // returns the number 4
+
+ +
注意: 其他的将字符串对象转换成基本字符串的方法可以及参考 StringView – a C-like representation of strings based on typed arrays.
+ +

属性

+ +
+
{{jsxref("String.prototype")}}
+
可以为 String 对象增加新的属性。
+
+ +

方法

+ +
+
{{jsxref("String.fromCharCode()")}}  
+
 通过一串 Unicode 创建字符串。
+
+ +
+
{{jsxref("String.fromCodePoint()")}} {{experimental_inline}}
+
通过一串 码点 创建字符串。
+
+ +
+
+
{{jsxref("String.raw()")}} {{experimental_inline}}
+
通过模板字符串创建字符串。
+
+
+ +

字符串泛型方法

+ +
+

字符串泛型是非标准的已弃用并且会在不远的将来删除。注意,你不能依靠他们的跨浏览器,而不使用下面提供的垫片。

+
+ +

应该避免在 Javascript 1.6 (Firefox 浏览器的 JS 引擎)中使用(虽然也支持)将其他对象转化为字符的方法,因为方法并没有成为 ECMA 标准:

+ +
let num = 15;
+console.log(String.replace(num, /5/, '2'));
+
+ +

移除字符串泛型的措施,参见 Warning: String.x is deprecated; use String.prototype.x instead.

+ +

{{jsxref("Global_Objects/Array", "Generics", "#Array_generic_methods", 1)}} 在 Javascript 1.6 中同样支持{{jsxref("Global_Objects/Array", "Array")}}。

+ +

String 实例

+ +

属性

+ +

{{page('zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/prototype', 'Properties')}}

+ +

{{page('zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/prototype', 'Methods')}}

+ +

示例 

+ +

将其他值转换成字符串

+ +

使用 String() 方法将其它对象转化为字符串可以被认为是一种更加安全的做法,虽然该方法底层使用的也是 toString() 方法,但是针对 null/undefined/symbols,String() 方法会有特殊的处理:

+ +
var outputStrings = [];
+for (let i = 0, n = inputValues.length; i < n; ++i) {
+  outputStrings.push(String(inputValues[i]));
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.5', 'String')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string-objects', 'String')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support0.2{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/indexof/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/indexof/index.html new file mode 100644 index 0000000000..5bb7b532fc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/indexof/index.html @@ -0,0 +1,181 @@ +--- +title: String.prototype.indexOf() +slug: Web/JavaScript/Reference/Global_Objects/String/indexOf +tags: + - JavaScript + - String + - 原型 + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/indexOf +--- +
{{JSRef}}
+ +

indexOf() 方法返回调用它的 {{jsxref("String")}} 对象中第一次出现的指定值的索引,从 fromIndex 处进行搜索。如果未找到该值,则返回 -1。

+ +
{{EmbedInteractiveExample("pages/js/string-indexof.html")}}
+ + + +
Note: For the Array method, see {{jsxref("Array.prototype.indexOf()")}}.
+ +

语法

+ +
str.indexOf(searchValue [, fromIndex])
+ +

参数

+ +
+
searchValue
+
要被查找的字符串值。
+
如果没有提供确切地提供字符串,searchValue 会被强制设置为 "undefined", 然后在当前字符串中查找这个值。
+
举个例子:'undefined'.indexOf() 将会返回0,因为 undefined 在位置0处被找到,但是 'undefine'.indexOf() 将会返回 -1 ,因为字符串 'undefined' 未被找到。
+
fromIndex {{optional_inline}}
+
数字表示开始查找的位置。可以是任意整数,默认值为 0
+
如果 fromIndex 的值小于 0,或者大于 str.length ,那么查找分别从 0 和str.length 开始。(译者注:  fromIndex 的值小于 0,等同于为空情况; fromIndex 的值大于或等于 str.length ,那么结果会直接返回 -1 。)
+
举个例子,'hello world'.indexOf('o', -5) 返回 4 ,因为它是从位置0处开始查找,然后 o 在位置4处被找到。另一方面,'hello world'.indexOf('o', 11) (或 fromIndex 填入任何大于11的值)将会返回 -1 ,因为开始查找的位置11处,已经是这个字符串的结尾了。
+
+ +

返回值

+ +

查找的字符串 searchValue 的第一次出现的索引,如果没有找到,则返回 -1

+ +

若被查找的字符串 searchValue 是一个空字符串,将会产生“奇怪”的结果。如果 fromIndex 值为空,或者 fromIndex 值小于被查找的字符串的长度,返回值和以下的 fromIndex 值一样:

+ +
'hello world'.indexOf('') // 返回 0
+'hello world'.indexOf('', 0) // 返回 0
+'hello world'.indexOf('', 3) // 返回 3
+'hello world'.indexOf('', 8) // 返回 8
+ +

另外,如果 fromIndex 值大于等于字符串的长度,将会直接返回字符串的长度(str.length):

+ +
'hello world'.indexOf('', 11) // 返回 11
+'hello world'.indexOf('', 13) // 返回 11
+'hello world'.indexOf('', 22) // 返回 11
+ +

从前面一个例子可以看出,被查找的值是空值时,Javascript将直接返回指定的索引值。从后面一个例子可以看出,被查找的值是空值时,Javascript将直接返回字符串的长度。

+ +

描述

+ +

字符串中的字符被从左向右索引。第一个字符的索引(index)是 0,变量名为 stringName 的字符串的最后一个字符的索引是 stringName.length - 1 。

+ +
"Blue Whale".indexOf("Blue")       // 返回 0
+"Blue Whale".indexOf("Blute")      // 返回 -1
+"Blue Whale".indexOf("Whale", 0)   // 返回 5
+"Blue Whale".indexOf("Whale", 5)   // 返回 5
+"Blue Whale".indexOf("", -1)       // 返回 0
+"Blue Whale".indexOf("", 9)        // 返回 9
+"Blue Whale".indexOf("", 10)       // 返回 10
+"Blue Whale".indexOf("", 11)       // 返回 10
+ +

indexOf 方法是区分大小写的。例如,下面的表达式将返回 -1

+ +
"Blue Whale".indexOf("blue")      // 返回 -1
+
+ +

检测是否存在某字符串

+ +

注意 0 并不会被当成 true-1 不会被当成 false 。所以当检测某个字符串是否存在于另一个字符串中时,可使用下面的方法:

+ +
'Blue Whale'.indexOf('Blue') !== -1    // true
+'Blue Whale'.indexOf('Bloe') !== -1    // false
+~('Blue Whale'.indexOf('Bloe'))        // 0, 这是一种错误用法
+ +

示例

+ +

使用indexOf() 和 lastIndexOf()

+ +

下例使用 indexOf()lastIndexOf() 方法定位字符串中 "Brave new world" 的值。

+ +
var anyString = "Brave new world";
+
+console.log("The index of the first w from the beginning is " + anyString.indexOf("w"));
+// logs 8
+console.log("The index of the first w from the end is " + anyString.lastIndexOf("w"));
+// logs 10
+
+console.log("The index of 'new' from the beginning is " + anyString.indexOf("new"));
+// logs 6
+console.log("The index of 'new' from the end is " + anyString.lastIndexOf("new"));
+// logs 6
+
+ +

indexOf 和区分大小写

+ +

下例定义了两个字符串变量。两个变量包含相同的字符串,除了第二个字符串中的某些字符为大写。第一个 log 方法输出 19。但是由于 indexOf 方法区分大小写,因此不会在 myCapString 中发现字符串 “cheddar",所以,第二个 log 方法会输出 -1。

+ +
var myString    = "brie, pepper jack, cheddar";
+var myCapString = "Brie, Pepper Jack, Cheddar";
+
+console.log('myString.indexOf("cheddar") is ' + myString.indexOf("cheddar"));
+// logs 19
+console.log('myCapString.indexOf("cheddar") is ' + myCapString.indexOf("cheddar"));
+// logs -1
+ +

使用 indexOf 统计一个字符串中某个字母出现的次数

+ +

在下例中,设置了 count 来记录字母 e 在字符串 str 中出现的次数:

+ +
// 翻译:生存还是毁灭?这是个问题。(莎士比亚《哈姆雷特》)
+var str = 'To be, or not to be, that is the question.';
+var count = 0;
+var pos = str.indexOf('e');
+
+while (pos !== -1) {
+  count++;
+  pos = str.indexOf('e', pos + 1);
+}
+
+console.log(count); // displays 4
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.5.4.7', 'String.prototype.indexOf')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.indexof', 'String.prototype.indexOf')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype.indexof', 'String.prototype.indexOf')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.indexOf")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/italics/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/italics/index.html new file mode 100644 index 0000000000..80ee07eabc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/italics/index.html @@ -0,0 +1,109 @@ +--- +title: String.prototype.italics() +slug: Web/JavaScript/Reference/Global_Objects/String/italics +translation_of: Web/JavaScript/Reference/Global_Objects/String/italics +--- +
{{JSRef}} {{deprecated_header}}
+ +

The italics() method creates an {{HTMLElement("i")}} HTML element that causes a string to be italic.

+ +

Syntax

+ +
str.italics()
+ +

Description

+ +

The italics() method embeds a string in an <i> tag: "<i>str</i>".

+ +

Examples

+ +

Using italics()

+ +

The following example uses string methods to change the formatting of a string:

+ +
var worldString = 'Hello, world'; console.log(worldString.blink());  // Hello, world
+console.log(worldString.bold());  // Hello, world
+console.log(worldString.italics()); //Hello, world
+console.log(worldString.strike());  // Hello, world
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.italics', 'String.prototype.italics')}}{{Spec2('ES6')}}Initial definition. Implemented in JavaScript 1.0. Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
{{SpecName('ESDraft', '#sec-string.prototype.italics', 'String.prototype.italics')}}{{Spec2('ESDraft')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/lastindexof/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/lastindexof/index.html new file mode 100644 index 0000000000..5dca3e48d4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/lastindexof/index.html @@ -0,0 +1,162 @@ +--- +title: String.prototype.lastIndexOf() +slug: Web/JavaScript/Reference/Global_Objects/String/lastIndexOf +translation_of: Web/JavaScript/Reference/Global_Objects/String/lastIndexOf +--- +

 {{JSRef}}

+ +

 lastIndexOf() 方法返回调用{{jsxref("String")}} 对象的指定值最后一次出现的索引,在一个字符串中的指定位置 fromIndex处从后向前搜索。如果没找到这个特定值则返回-1 。

+ +

该方法将从尾到头地检索字符串 str,看它是否含有子串 searchValue。开始检索的位置在字符串的 fromIndex 处或字符串的结尾(没有指定 fromIndex 时)。如果找到一个 searchValue,则返回 searchValue 的第一个字符在 str 中的位置。str中的字符位置是从 0 开始的。

+ +

语法

+ +
str.lastIndexOf(searchValue[, fromIndex])
+ +

参数

+ +
+
searchValue
+
一个字符串,表示被查找的值。如果searchValue是空字符串,则返回fromIndex
+
fromIndex{{optional_inline}}
+
待匹配字符串searchValue的开头一位字符从 str的第fromIndex位开始向左回向查找。fromIndex默认值是 +Infinity。如果 fromIndex >= str.length ,则会搜索整个字符串。如果 fromIndex < 0 ,则等同于 fromIndex == 0
+
+

返回值

+
+
+ +

返回指定值最后一次出现的索引(该索引仍是以从左至右0开始记数的),如果没找到则返回-1。

+ +

描述

+ +

字符串中的字符被从左向右索引。首字符的索引(index)是 0,最后一个字符的索引是 stringName.length - 1

+ +
'canal'.lastIndexOf('a');     // returns 3 (没有指明fromIndex则从末尾l处开始反向检索到的第一个a出现在l的后面,即index为3的位置)
+'canal'.lastIndexOf('a', 2);  // returns 1(指明fromIndex为2则从n处反向向回检索到其后面就是a,即index为1的位置)
+'canal'.lastIndexOf('a', 0);  // returns -1(指明fromIndex为0则从c处向左回向检索a发现没有,故返回-1)
+'canal'.lastIndexOf('x');     // returns -1
+'canal'.lastIndexOf('c', -5); // returns 0(指明fromIndex为-5则视同0,从c处向左回向查找发现自己就是,故返回0)
+'canal'.lastIndexOf('c', 0);  // returns 0(指明fromIndex为0则从c处向左回向查找c发现自己就是,故返回自己的索引0)
+'canal'.lastIndexOf('');      // returns 5
+'canal'.lastIndexOf('', 2);   // returns 2
+
+ +
+

Note: 'abab'.lastIndexOf('ab', 2) 将返回 2 而不是 0, 因为fromIndex只限制待匹配字符串的开头。

+
+ +

(例如'abadefgabm'.lastIndexOf('ab', 7) 返回7,虽然查找的'ab'中的b已经在 index=8的位置了从index=7的a处向左查找仍是能找到自身a加上其后连成ab,因为fromIndex指的是待匹配字符串的开头那一个)

+ +

区分大小写

+ +

lastIndexOf 方法区分大小写。例如,下面的表达式返回 -1:

+ +
"Blue Whale, Killer Whale".lastIndexOf("blue"); // returns -1
+ +

示例

+ +

例子:使用 indexOflastIndexOf

+ +

下例使用 indexOf 和 lastIndexOf 方法来定位字符串 "Brave new world" 中的值。

+ +
var anyString = "Brave new world";
+
+console.log("The index of the first w from the beginning is " + anyString.indexOf("w"));
+// Displays 8
+console.log("The index of the first w from the end is " + anyString.lastIndexOf("w"));
+// Displays 10
+
+console.log("The index of 'new' from the beginning is " + anyString.indexOf("new"));
+// Displays 6
+console.log("The index of 'new' from the end is " + anyString.lastIndexOf("new"));
+// Displays 6
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.5.4.8', 'String.prototype.lastIndexOf')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.lastindexof', 'String.prototype.lastIndexOf')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/length/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/length/index.html new file mode 100644 index 0000000000..c51f812f6d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/length/index.html @@ -0,0 +1,135 @@ +--- +title: String.length +slug: Web/JavaScript/Reference/Global_Objects/String/length +tags: + - JavaScript + - Property + - Prototype + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/length +--- +

{{JSRef("Global_Objects", "String")}}

+ +

概述

+ +

length 属性表示一个字符串的长度。

+ +

描述

+ +

该属性返回字符串中字符编码单元的数量。JavaScript 使用 {{ interwiki("wikipedia", "UTF-16") }} 编码,该编码使用一个 16 比特的编码单元来表示大部分常见的字符,使用两个代码单元表示不常用的字符。因此 length 返回值可能与字符串中实际的字符数量不相同。

+ +

空字符串的 length 为 0。

+ +

静态属性 String.length 返回 1。

+ +

示例

+ +
var x = "Mozilla";
+var empty = "";
+
+console.log("Mozilla is " + x.length + " code units long");
+/* "Mozilla is 7 code units long" */
+
+console.log("The empty string is has a length of " + empty.length);
+/* "The empty string is has a length of 0" */
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +
 
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.5.5.1', 'String.prototype.length')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-string-instances-length', 'String.prototype.length')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/link/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/link/index.html new file mode 100644 index 0000000000..a3956f9ba7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/link/index.html @@ -0,0 +1,76 @@ +--- +title: String.prototype.link() +slug: Web/JavaScript/Reference/Global_Objects/String/link +translation_of: Web/JavaScript/Reference/Global_Objects/String/link +--- +
{{JSRef}} {{deprecated_header}}
+ +

link() 方法创建一个 HTML 元素 {{HTMLElement("a")}} ,用该字符串作为超链接的显示文本,参数作为指向另一个 URL 的超链接。

+ +

语法

+ +
str.link(url)
+ +

参数

+ +
+
url
+
任何能够指定 a 标签的 href 属性的字符串;它应当是有效的 URL(相对或绝对),任何 & 字符将会被转义为 &amp;,任何 " 字符将会被转义为 &quot;
+
+ +

返回值

+ +

一个带有一个 HTML 元素 {{HTMLElement("a")}} 的字符串。

+ +

描述

+ +

使用 link 方法创建一个超链接 HTML 片段。返回的字符串可以通过 {{ Domxref("document.write") }} 或 {{ Domxref("element.innerHTML") }} 方法添加到文档中。

+ +

使用 link 方法创建的链接将会成为 document.links 数组中的元素。查看 {{ Domxref("document.links") }}。

+ +

示例

+ + + +

下例显示一个单词 "MDN" 作为超链接,指向 Mozilla Developer Network。

+ +
var hotText = 'MDN';
+var URL = 'https://developer.mozilla.org/';
+
+document.write('Click to return to ' + hotText.link(URL));
+// Click to return to <a href="https://developer.mozilla.org/">MDN</a>
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.link', 'String.prototype.link')}}{{Spec2('ES6')}}Initial definition. Implemented in JavaScript 1.0. Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
{{SpecName('ESDraft', '#sec-string.prototype.link', 'String.prototype.link')}}{{Spec2('ESDraft')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.link")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/localecompare/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/localecompare/index.html new file mode 100644 index 0000000000..b3607222de --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/localecompare/index.html @@ -0,0 +1,185 @@ +--- +title: String.prototype.localeCompare() +slug: Web/JavaScript/Reference/Global_Objects/String/localeCompare +tags: + - Internationalization + - JavaScript + - String.prototype.localeCompare() + - 原型 + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/localeCompare +--- +
{{JSRef}}
+ +

localeCompare() 方法返回一个数字来指示一个参考字符串是否在排序顺序前面或之后或与给定字符串相同。

+ +

新的 locales 、 options 参数能让应用程序定制函数的行为即指定用来排序的语言。  localesoptions 参数是依赖于具体实现的,在旧的实现中这两个参数是完全被忽略的。

+ +

语法

+ +
referenceStr.localeCompare(compareString[, locales[, options]])
+ +

参数

+ +

查阅浏览器支持部分来确定哪些浏览器支持 locales 参数和 options 参数, 在功能检测中检查对 localesoptions 参数的支持

+ +
+
compareString
+
用来比较的字符串
+
locales
+
可选。 用来表示一种或多种语言或区域的一个符合 BCP 47 标准的字符串或一个字符串数组。 locales参数的一般形式与解释, 详情请参考 Intl page。 下列的 Unicode 扩展关键词是允许的:
+
co
+
为了某些地域多样的排序规则。可能的值包括: "big5han""dict""direct""ducet""gb2312""phonebk""phonetic""pinyin""reformed""searchjl""stroke""trad""unihan"。 "standard" 和"search" 这两个值是被忽略的; 它们被 options 的属性 usage 代替(往下看)。
+
kn
+
指定数值排序是否应该被使用, 像是这样 "1" < "2" < "10"。 可能的值是 "true" 和 "false"。 这个选项能被通过options 属性设置或通过 Unicode 扩展。 假如两个都被设置了, 则 options 优先。("language-region-u-kn-true|false")
+
kf
+
指定是否优先对大写字母或小写字母排序。 可能的值有 "upper""lower", 或 "false" (use the locale's default)。这个选项能被通过options 属性设置或通过 Unicode 扩展。假如两个都被设置了, 则 options 优先。("language-region-u-kf-upper|lower|false")
+
options
+
+

可选。 支持下列的一些或全部属性的一个对象:

+ +
+
localeMatcher
+
地域匹配算法的使用. 可能的值是 "lookup" 和 "best fit"; 默认的值是 "best fit"。更多相关的资料, 请参考 Intl page.
+
usage
+
指定比较的目标是排序或者是搜索. 可能的值是 "sort" 和 "search"; 默认是 "sort".
+
sensitivity
+
+

指定排序程序的敏感度(Which differences in the strings should lead to non-zero result values.) 可能的有:

+ +
    +
  • "base": 只有不同的字母字符串比较是不相等的. 举个例子: a ≠ ba = áa = A.
  • +
  • "accent": 只有不同的字母或读音比较是不相等的. 举个例子: a ≠ ba ≠ áa = A.
  • +
  • "case": 只有不同的字母或大小写比较是不相等的. 举个例子: a ≠ ba = áa ≠ A.
  • +
  • "variant": 不同的字母或读音及其它有区别的标志或大小写都是不相等的, 还有其它的差异可能也会考虑到. 举个例子: a ≠ ba ≠ áa ≠ A.
  • +
+ +

The default is "variant" for usage "sort"; it's locale dependent for usage "search".

+
+
ignorePunctuation
+
指定是否忽略标点. 可能的值是 true and false; 默认为 false.
+
numeric
+
是否指定使用数字排序, 像这样 "1" < "2" < "10". 可能的值是 true 和 false; 默认为 false. 这个选项能被通过options 属性设置或通过 Unicode 扩展。假如两个都被设置了, 则 options 优先。 实现不用必须支持这个属性.
+
caseFirst
+
指定大小写有限排序. 可能的值有 "upper""lower", or "false" (use the locale's default); 默认为 "false". 这个选项能被通过options 属性设置或通过 Unicode 扩展。假如两个都被设置了, 则 options 优先。 实现不用必须支持这个属性.
+
+
+
+

返回值

+ +

如果引用字符存在于比较字符之前则为负数; 如果引用字符存在于比较字符之后则为正数; 相等的时候返回 0 .

+
+
page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Collator', 'Parameters')}}
+
+ +

描述

+ +

返回一个数字表示是否 引用字符串 在排序中位于 比较字符串 的前面,后面,或者二者相同。

+ + + +

切勿依赖于 -1 或 1 这样特定的返回值。不同浏览器之间(以及不同浏览器版本之间) 返回的正负数的值各有不同,因为W3C规范中只要求返回值是正值和负值,而没有规定具体的值。一些浏览器可能返回-2或2或其他一些负的、正的值。

+ +

示例

+ +

使用 localeCompare()

+ +
// The letter "a" is before "c" yielding a negative value
+'a'.localeCompare('c');
+// -2 or -1 (or some other negative value)
+
+// Alphabetically the word "check" comes after "against" yielding a positive value
+'check'.localeCompare('against');
+// 2 or 1 (or some other positive value)
+
+// "a" and "a" are equivalent yielding a neutral value of zero
+'a'.localeCompare('a');
+// 0
+
+ +

检查浏览器对扩展参数的支持

+ +

locales 和 options 参数还没有被所有浏览器所支持。检查是否被支持, 使用 "i" 参数 (a requirement that illegal language tags are rejected) 判断是否有异常 {{jsxref("RangeError")}}抛出:

+ +
function localeCompareSupportsLocales() {
+  try {
+    'foo'.localeCompare​('bar', 'i');
+  } catch (e) {
+    return e​.name === 'RangeError';
+  }
+  return false;
+}
+
+ +

使用 locales 参数

+ +

在不同的语言下 localeCompare() 所提供的结果是不一致的。 为了能让用户得到正确的比较值, 通过使用 locales 参数来提供要比较的语言 (and possibly some fallback languages) :

+ +
console.log('ä'.localeCompare('z', 'de')); // a negative value: in German, ä sorts with a
+console.log('ä'.localeCompare('z', 'sv')); // a positive value: in Swedish, ä sorts after z
+
+ +

使用 options 参数

+ +

localeCompare() 所提供的结果可以通过 options 参数来制定:

+ +
// in German, ä has a as the base letter
+console.log('ä'.localeCompare('a', 'de', { sensitivity: 'base' })); // 0
+
+// in Swedish, ä and a are separate base letters
+console.log('ä'.localeCompare('a', 'sv', { sensitivity: 'base' })); // a positive value
+
+ +

性能相关

+ +

当比较大量字符串时, 比如比较大量数组时, 最好创建一个{{jsxref("Global_Objects/Collator", "Intl.Collator")}} 对象并使用{{jsxref("Collator.prototype.compare", "compare")}} 属性所提供的函数。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.5.4.9', 'String.prototype.localeCompare')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.localecompare', 'String.prototype.localeCompare')}}{{Spec2('ES6')}}
{{SpecName('ES Int 1.0', '#sec-13.1.1', 'String.prototype.localeCompare')}}{{Spec2('ES Int 1.0')}}locale and option parameter definitions.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.localeCompare")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/match/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/match/index.html new file mode 100644 index 0000000000..9922ea3291 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/match/index.html @@ -0,0 +1,215 @@ +--- +title: String.prototype.match() +slug: Web/JavaScript/Reference/Global_Objects/String/match +translation_of: Web/JavaScript/Reference/Global_Objects/String/match +--- +

{{JSRef}}

+ +

 match() 方法检索返回一个字符串匹配正则表达式的结果。

+ + +
{{EmbedInteractiveExample("pages/js/string-match.html", "shorter")}}
+ + + +

语法

+ +
str.match(regexp)
+ +

参数

+ +
+
regexp
+
一个正则表达式对象。如果传入一个非正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个 {{jsxref("RegExp")}} 。如果你没有给出任何参数并直接使用match() 方法 ,你将会得到一 个包含空字符串的 {{jsxref("Array")}} :[""] 。
+
+ +

返回值

+ + + +

附加属性

+ +

如上所述,匹配的结果包含如下所述的附加特性。

+ + + +
+
一个{{jsxref("Array")}},其内容取决于global(g)标志的存在与否,如果未找到匹配则为{{jsxref("null")}}。
+
+ +

描述

+ +

如果正则表达式不包含 标志,str.match() 将返回与 {{jsxref("RegExp.prototype.exec()", "RegExp.exec()")}}. 相同的结果。

+ +

参看:RegExp 方法

+ + + +

示例

+ +

例子:使用 match

+ +

在下例中,使用 match 查找 "Chapter" 紧跟着 1 个或多个数值字符,再紧跟着一个小数点和数值字符 0 次或多次。正则表达式包含 i 标志,因此大小写会被忽略。

+ +
var str = 'For more information, see Chapter 3.4.5.1';
+var re = /see (chapter \d+(\.\d)*)/i;
+var found = str.match(re);
+
+console.log(found);
+
+// logs [ 'see Chapter 3.4.5.1',
+//        'Chapter 3.4.5.1',
+//        '.1',
+//        index: 22,
+//        input: 'For more information, see Chapter 3.4.5.1' ]
+
+// 'see Chapter 3.4.5.1' 是整个匹配。
+// 'Chapter 3.4.5.1' 被'(chapter \d+(\.\d)*)'捕获。
+// '.1' 是被'(\.\d)'捕获的最后一个值。
+// 'index' 属性(22) 是整个匹配从零开始的索引。
+// 'input' 属性是被解析的原始字符串。
+ +

例子:match 使用全局(global)和忽略大小写(ignore case)标志

+ +

下例展示了 match 使用 global 和 ignore case 标志。A-E、a-e 的所有字母将会作为一个数组的元素返回。

+ +
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+var regexp = /[A-E]/gi;
+var matches_array = str.match(regexp);
+
+console.log(matches_array);
+// ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']
+ +

使用match(),不传参数

+ +
var str = "Nothing will come of nothing.";
+
+str.match();   // returns [""]
+ +

一个非正则表达式对象作为参数

+ +

当参数是一个字符串或一个数字,它会使用new RegExp(obj)来隐式转换成一个 {{jsxref("RegExp")}}。如果它是一个有正号的正数,RegExp() 方法将忽略正号。

+ +
var str1 = "NaN means not a number. Infinity contains -Infinity and +Infinity in JavaScript.",
+    str2 = "My grandfather is 65 years old and My grandmother is 63 years old.",
+    str3 = "The contract was declared null and void.";
+str1.match("number");   // "number" 是字符串。返回["number"]
+str1.match(NaN);        // NaN的类型是number。返回["NaN"]
+str1.match(Infinity);   // Infinity的类型是number。返回["Infinity"]
+str1.match(+Infinity);  // 返回["Infinity"]
+str1.match(-Infinity);  // 返回["-Infinity"]
+str2.match(65);         // 返回["65"]
+str2.match(+65);        // 有正号的number。返回["65"]
+str3.match(null);       // 返回["null"]
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.5.4.10', 'String.prototype.match')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.match', 'String.prototype.match')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype.match', 'String.prototype.match')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Firefox 特殊注意

+ + + +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/matchall/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/matchall/index.html new file mode 100644 index 0000000000..5fd54c46aa --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/matchall/index.html @@ -0,0 +1,135 @@ +--- +title: String.prototype.matchAll() +slug: Web/JavaScript/Reference/Global_Objects/String/matchAll +tags: + - JavaScript + - Method + - Prototype + - Reference + - Regular Expressions + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/matchAll +--- +
{{JSRef}}
+ +

matchAll() 方法返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。

+ +
{{EmbedInteractiveExample("pages/js/string-matchall.html")}}
+ + + +

语法

+ +
str.matchAll(regexp)
+ +

参数

+ +
+
regexp
+
+ +

    正则表达式对象。如果所传参数不是一个正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个 RegExp 。

+ +

    RegExp必须是设置了全局模式g的形式,否则会抛出异常TypeError

+ +

返回值

+ +

一个迭代器(不可重用,结果耗尽需要再次调用方法,获取一个新的迭代器)。

+ +

例子

+ +

Regexp.exec() 和 matchAll()

+ +

matchAll 出现之前,通过在循环中调用 regexp.exec() 来获取所有匹配项信息(regexp 需使用 /g 标志):

+ +
const regexp = RegExp('foo[a-z]*','g');
+const str = 'table football, foosball';
+let match;
+
+while ((match = regexp.exec(str)) !== null) {
+  console.log(`Found ${match[0]} start=${match.index} end=${regexp.lastIndex}.`);
+  // expected output: "Found football start=6 end=14."
+  // expected output: "Found foosball start=16 end=24."
+}
+ +

如果使用 matchAll ,就可以不必使用 while 循环加 exec 方式(且正则表达式需使用 /g 标志)。使用 matchAll 会得到一个迭代器的返回值,配合 for...of, array spread, 或者 {{jsxref("Array.from()")}} 可以更方便实现功能:

+ +
const regexp = RegExp('foo[a-z]*','g');
+const str = 'table football, foosball';
+const matches = str.matchAll(regexp);
+
+for (const match of matches) {
+  console.log(`Found ${match[0]} start=${match.index} end=${match.index + match[0].length}.`);
+}
+// expected output: "Found football start=6 end=14."
+// expected output: "Found foosball start=16 end=24."
+
+// matches iterator is exhausted after the for..of iteration
+// Call matchAll again to create a new iterator
+Array.from(str.matchAll(regexp), m => m[0]);
+// Array [ "football", "foosball" ]
+ +

如果没有 /g 标志,matchAll 会抛出异常。

+ +
const regexp = RegExp('[a-c]','');
+const str = 'abc';
+Array.from(str.matchAll(regexp), m => m[0]);
+// TypeError: String.prototype.matchAll called with a non-global RegExp argument
+ +

matchAll 内部做了一个 regexp 的复制,所以不像 regexp.execlastIndex 在字符串扫描时不会改变。

+ +
const regexp = RegExp('[a-c]','g');
+regexp.lastIndex = 1;
+const str = 'abc';
+Array.from(str.matchAll(regexp), m => `${regexp.lastIndex} ${m[0]}`);
+// Array [ "1 b", "1 c" ]
+
+ +

捕获组的更佳途径

+ +

matchAll 的另外一个亮点是更好地获取捕获组。因为当使用 match() 和 /g 标志方式获取匹配信息时,捕获组会被忽略:

+ +
var regexp = /t(e)(st(\d?))/g;
+var str = 'test1test2';
+
+str.match(regexp);
+// Array ['test1', 'test2']
+ +

使用 matchAll 可以通过如下方式获取分组捕获:

+ +
let array = [...str.matchAll(regexp)];
+
+array[0];
+// ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
+array[1];
+// ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]
+
+ +

规范

+ + + + + + + + + + + + +
SpecificationStatus
{{SpecName('ESDraft', '#sec-string.prototype.matchall', 'String.prototype.matchAll')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.matchAll")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/normalize/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/normalize/index.html new file mode 100644 index 0000000000..3a054a9172 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/normalize/index.html @@ -0,0 +1,231 @@ +--- +title: String.prototype.normalize() +slug: Web/JavaScript/Reference/Global_Objects/String/normalize +tags: + - ECMAScript 2015 + - JavaScript + - Method + - String + - Unicode + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/normalize +--- +

{{JSRef}}

+ +

normalize() 方法会按照指定的一种 Unicode 正规形式将当前字符串正规化。(如果该值不是字符串,则首先将其转换为一个字符串)。

+ +
{{EmbedInteractiveExample("pages/js/string-normalize.html", "taller")}}
+ + + +

语法

+ +
str.normalize([form])
+ +

参数

+ +
+
form {{optional_inline}}
+
+

四种 Unicode 正规形式(Unicode Normalization Form)"NFC""NFD""NFKC",或 "NFKD" 其中的一个, 默认值为 "NFC"

+ +

这四个值的含义分别如下:

+ +
+
"NFC"
+
Canonical Decomposition, followed by Canonical Composition.
+
"NFD"
+
Canonical Decomposition.
+
"NFKC"
+
Compatibility Decomposition, followed by Canonical Composition.
+
"NFKD"
+
Compatibility Decomposition.
+
+
+
+ +

返回值

+ +

含有给定字符串的 Unicode 规范化形式的字符串。

+ +

可能出现的异常

+ +
+
{{jsxref("RangeError")}}
+
如果给 form 传入了上述四个字符串以外的参数,则会抛出 RangeError 异常。
+
+ +

描述

+ +

Unicode assigns a unique numerical value, called a code point, to each character. For example, the code point for "A" is given as U+0041. However, sometimes more than one code point, or sequence of code points, can represent the same abstract character — the character "ñ" for example can be represented by either of:

+ + + +
let string1 = '\u00F1';
+let string2 = '\u006E\u0303';
+
+console.log(string1);  //  ñ
+console.log(string2);  //  ñ
+
+ +

However, since the code points are different, string comparison will not treat them as equal. And since the number of code points in each version is different, they even have different lengths.

+ +
let string1 = '\u00F1';            // ñ
+let string2 = '\u006E\u0303';      // ñ
+
+console.log(string1 === string2); // false
+console.log(string1.length);      // 1
+console.log(string2.length);      // 2
+
+ +

The normalize() method helps solve this problem by converting a string into a normalized form common for all sequences of code points that represent the same characters. There are two main normalization forms, one based on canonical equivalence and the other based on compatibility.

+ +

Canonical equivalence normalization

+ +

In Unicode, two sequences of code points have canonical equivalence if they represent the same abstract characters, and should always have the same visual appearance and behavior (for example, they should always be sorted in the same way).

+ +

You can use normalize() using the "NFD" or "NFC" arguments to produce a form of the string that will be the same for all canonically equivalent strings. In the example below we normalize two representations of the character "ñ":

+ +
let string1 = '\u00F1';           // ñ
+let string2 = '\u006E\u0303';     // ñ
+
+string1 = string1.normalize('NFD');
+string2 = string2.normalize('NFD');
+
+console.log(string1 === string2); // true
+console.log(string1.length);      // 2
+console.log(string2.length);      // 2
+
+ +

Composed and decomposed forms

+ +

Note that the length of the normalized form under "NFD" is 2. That's because "NFD" gives you the decomposed version of the canonical form, in which single code points are split into multiple combining ones. The decomposed canonical form for "ñ" is "\u006E\u0303".

+ +

You can specify "NFC" to get the composed canonical form, in which multiple code points are replaced with single code points where possible. The composed canonical form for "ñ" is "\u00F1":

+ +
let string1 = '\u00F1';                           // ñ
+let string2 = '\u006E\u0303';                     // ñ
+
+string1 = string1.normalize('NFC');
+string2 = string2.normalize('NFC');
+
+console.log(string1 === string2);                 // true
+console.log(string1.length);                      // 1
+console.log(string2.length);                      // 1
+console.log(string2.codePointAt(0).toString(16)); // f1
+ +

Compatibility normalization

+ +

In Unicode, two sequences of code points are compatible if they represent the same abstract characters, and should be treated alike in some — but not necessarily all — applications.

+ +

All canonically equivalent sequences are also compatible, but not vice versa.

+ +

For example, the code point U+FB00 represents the ligature "ff". It is compatible with two consecutive U+0066 code points ("ff").

+ +

In some respects (such as sorting) they should be treated as equivalent—and in some (such as visual appearance) they should not, so they are not canonically equivalent.

+ +

You can use normalize() using the "NFKD" or "NFKC" arguments to produce a form of the string that will be the same for all compatible strings:

+ +
let string1 = '\uFB00';
+let string2 = '\u0066\u0066';
+
+console.log(string1);             // ff
+console.log(string2);             // ff
+console.log(string1 === string2); // false
+console.log(string1.length);      // 1
+console.log(string2.length);      // 2
+
+string1 = string1.normalize('NFKD');
+string2 = string2.normalize('NFKD');
+
+console.log(string1);             // ff <- visual appearance changed
+console.log(string2);             // ff
+console.log(string1 === string2); // true
+console.log(string1.length);      // 2
+console.log(string2.length);      // 2
+
+ +

When applying compatibility normalization it's important to consider what you intend to do with the strings, since the normalized form may not be appropriate for all applications. In the example above the normalization is appropriate for search, because it enables a user to find the string by searching for "f". But it may not be appropriate for display, because the visual representation is different.

+ +

As with canonical normalization, you can ask for decomposed or composed compatible forms by passing "NFKD" or "NFKC", respectively.

+ +

示例

+ +

使用 normalize()

+ +
// Initial string
+
+// U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE
+// U+0323: COMBINING DOT BELOW
+var str = "\u1E9B\u0323";
+
+
+// Canonically-composed form (NFC)
+
+// U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE
+// U+0323: COMBINING DOT BELOW
+str.normalize("NFC"); // "\u1E9B\u0323"
+str.normalize(); // same as above
+
+
+// Canonically-decomposed form (NFD)
+
+// U+017F: LATIN SMALL LETTER LONG S
+// U+0323: COMBINING DOT BELOW
+// U+0307: COMBINING DOT ABOVE
+str.normalize("NFD"); // "\u017F\u0323\u0307"
+
+
+// Compatibly-composed (NFKC)
+
+// U+1E69: LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
+str.normalize("NFKC"); // "\u1E69"
+
+
+// Compatibly-decomposed (NFKD)
+
+// U+0073: LATIN SMALL LETTER S
+// U+0323: COMBINING DOT BELOW
+// U+0307: COMBINING DOT ABOVE
+str.normalize("NFKD"); // "\u0073\u0323\u0307"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-string.prototype.normalize', 'String.prototype.normalize')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-string.prototype.normalize', 'String.prototype.normalize')}}{{Spec2('ES2015')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.normalize")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/padend/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/padend/index.html new file mode 100644 index 0000000000..4b06856b03 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/padend/index.html @@ -0,0 +1,100 @@ +--- +title: String.prototype.padEnd() +slug: Web/JavaScript/Reference/Global_Objects/String/padEnd +tags: + - JavaScript + - Method + - Reference + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/padEnd +--- +
{{JSRef}}
+ +

padEnd()  方法会用一个字符串填充当前字符串(如果需要的话则重复填充),返回填充后达到指定长度的字符串。从当前字符串的末尾(右侧)开始填充。

+ +
{{EmbedInteractiveExample("pages/js/string-padend.html")}}
+ + + +

语法

+ +
str.padEnd(targetLength [, padString])
+ +

参数

+ +
+
targetLength
+
当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
+
padString {{optional_inline}}
+
填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。此参数的缺省值为 " "(U+0020)。
+
+ +

返回值

+ +

在原字符串末尾填充指定的填充字符串直到目标长度所形成的新字符串。

+ +

示例

+ +
'abc'.padEnd(10);          // "abc       "
+'abc'.padEnd(10, "foo");   // "abcfoofoof"
+'abc'.padEnd(6, "123456"); // "abc123"
+'abc'.padEnd(1);           // "abc"
+
+ +

Polyfill

+ +

如果原生环境不支持该方法,在其他代码之前先运行下面的代码,将创建 String.prototype.padEnd() 方法。

+ +
// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
+if (!String.prototype.padEnd) {
+    String.prototype.padEnd = function padEnd(targetLength,padString) {
+        targetLength = targetLength>>0; //floor if number or convert non-number to 0;
+        padString = String((typeof padString !== 'undefined' ? padString: ''));
+        if (this.length > targetLength) {
+            return String(this);
+        }
+        else {
+            targetLength = targetLength-this.length;
+            if (targetLength > padString.length) {
+                padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
+            }
+            return String(this) + padString.slice(0,targetLength);
+        }
+    };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-string.prototype.padend', 'String.prototype.padEnd')}}{{Spec2('ESDraft')}}在 ECMAScript 2017 中首次被定义。
{{SpecName('ES8', '#sec-string.prototype.padend', 'String.prototype.padEnd')}}{{Spec2('ES8')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.padEnd")}}

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/padstart/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/padstart/index.html new file mode 100644 index 0000000000..24431715d0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/padstart/index.html @@ -0,0 +1,102 @@ +--- +title: String.prototype.padStart() +slug: Web/JavaScript/Reference/Global_Objects/String/padStart +tags: + - ECMAScript 2017 + - JavaScript + - Method + - Reference + - String + - String.padStart() +translation_of: Web/JavaScript/Reference/Global_Objects/String/padStart +--- +
{{JSRef}}
+ +

padStart() 方法用另一个字符串填充当前字符串(如果需要的话,会重复多次),以便产生的字符串达到给定的长度。从当前字符串的左侧开始填充。

+ +
{{EmbedInteractiveExample("pages/js/string-padstart.html")}}
+ + + +

语法

+ +
str.padStart(targetLength [, padString])
+ +

参数

+ +
+
targetLength
+
当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
+
padString {{optional_inline}}
+
填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。此参数的默认值为 " "(U+0020)。
+
+ +

返回值

+ +

在原字符串开头填充指定的填充字符串直到目标长度所形成的新字符串。

+ +

示例

+ +
'abc'.padStart(10);         // "       abc"
+'abc'.padStart(10, "foo");  // "foofoofabc"
+'abc'.padStart(6,"123465"); // "123abc"
+'abc'.padStart(8, "0");     // "00000abc"
+'abc'.padStart(1);          // "abc"
+ +

Polyfill

+ +

如果原生环境不支持该方法,在其他代码之前先运行下面的代码,将创建 String.prototype.padStart() 方法。

+ +
// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
+if (!String.prototype.padStart) {
+    String.prototype.padStart = function padStart(targetLength,padString) {
+        targetLength = targetLength>>0; //floor if number or convert non-number to 0;
+        padString = String((typeof padString !== 'undefined' ? padString : ' '));
+        if (this.length > targetLength) {
+            return String(this);
+        }
+        else {
+            targetLength = targetLength-this.length;
+            if (targetLength > padString.length) {
+                padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
+            }
+            return padString.slice(0,targetLength) + String(this);
+        }
+    };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-string.prototype.padstart', 'String.prototype.padStart')}}{{Spec2('ESDraft')}}在 ECMAScript 2017 中首次被定义。
{{SpecName('ES8', '#sec-string.prototype.padstart', 'String.prototype.padStart')}}{{Spec2('ES8')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.padStart")}}

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/prototype/index.html new file mode 100644 index 0000000000..88b792052b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/prototype/index.html @@ -0,0 +1,186 @@ +--- +title: String.prototype +slug: Web/JavaScript/Reference/Global_Objects/String/prototype +tags: + - JavaScript + - 原型 + - 参考 + - 字符串 + - 属性 +translation_of: Web/JavaScript/Reference/Global_Objects/String +--- +
{{JSRef}}
+ +

 String.prototype 属性表示 {{jsxref("String")}}原型对象。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

所有 {{jsxref("String")}} 的实例都继承自 String.prototype. 任何String.prototype上的改变都会影响到所有的 {{jsxref("String")}} 实例。

+ +

属性

+ +
+
String.prototype.constructor
+
用于创造对象的原型对象的特定的函数。
+
{{jsxref("String.prototype.length")}}
+
返回了字符串的长度。
+
N
+
用于访问第N个位置的字符,其中N是小于 {{jsxref("String.length", "length")}} 和 0之间的正整数。这些属性都是“只读”性质,不能编辑。
+
+ +

方法

+ +

跟HTML无关的方法

+ +
+
{{jsxref("String.prototype.charAt()")}}
+
返回特定位置的字符。
+
{{jsxref("String.prototype.charCodeAt()")}}
+
返回表示给定索引的字符的Unicode的值。
+
{{jsxref("String.prototype.codePointAt()")}}
+
返回使用UTF-16编码的给定位置的值的非负整数。
+
{{jsxref("String.prototype.concat()")}}
+
连接两个字符串文本,并返回一个新的字符串。
+
{{jsxref("String.prototype.includes()")}}
+
判断一个字符串里是否包含其他字符串。
+
{{jsxref("String.prototype.endsWith()")}}
+
判断一个字符串的是否以给定字符串结尾,结果返回布尔值。
+
{{jsxref("String.prototype.indexOf()")}}
+
从字符串对象中返回首个被发现的给定值的索引值,如果没有找到则返回-1。
+
{{jsxref("String.prototype.lastIndexOf()")}}
+
从字符串对象中返回最后一个被发现的给定值的索引值,如果没有找到则返回-1。
+
{{jsxref("String.prototype.localeCompare()")}}
+
返回一个数字表示是否引用字符串在排序中位于比较字符串的前面,后面,或者二者相同。
+
{{jsxref("String.prototype.match()")}}
+
使用正则表达式与字符串相比较。
+
{{jsxref("String.prototype.normalize()")}}
+
返回调用字符串值的Unicode标准化形式。
+
{{jsxref("String.prototype.padEnd()")}}
+
在当前字符串尾部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串。
+
{{jsxref("String.prototype.padStart()")}}
+
+

在当前字符串头部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串。

+
+
{{jsxref("String.prototype.quote()")}} {{ obsolete_inline }}
+
设置嵌入引用的引号类型。
+
{{jsxref("String.prototype.repeat()")}}
+
返回指定重复次数的由元素组成的字符串对象。
+
{{jsxref("String.prototype.replace()")}}
+
被用来在正则表达式和字符串直接比较,然后用新的子串来替换被匹配的子串。
+
{{jsxref("String.prototype.search()")}}
+
对正则表达式和指定字符串进行匹配搜索,返回第一个出现的匹配项的下标。
+
{{jsxref("String.prototype.slice()")}}
+
摘取一个字符串区域,返回一个新的字符串。
+
{{jsxref("String.prototype.split()")}}
+
通过分离字符串成字串,将字符串对象分割成字符串数组。
+
{{jsxref("String.prototype.startsWith()")}}
+
判断字符串的起始位置是否匹配其他字符串中的字符。
+
{{jsxref("String.prototype.substr()")}}
+
通过指定字符数返回在指定位置开始的字符串中的字符。
+
{{jsxref("String.prototype.substring()")}}
+
返回在字符串中指定两个下标之间的字符。
+
{{jsxref("String.prototype.toLocaleLowerCase()")}}
+
根据当前区域设置,将符串中的字符转换成小写。对于大多数语言来说,{{jsxref("String.toLowerCase", "toLowerCase")}}的返回值是一致的。
+
{{jsxref("String.prototype.toLocaleUpperCase()")}}
+
根据当前区域设置,将字符串中的字符转换成大写,对于大多数语言来说,{{jsxref("String.toUpperCase", "toUpperCase")}}的返回值是一致的。
+
{{jsxref("String.prototype.toLowerCase()")}}
+
将字符串转换成小写并返回。
+
{{jsxref("String.prototype.toSource()")}} {{ Non-standard_inline() }}
+
返回一个对象文字代表着特定的对象。你可以使用这个返回值来创建新的对象。重写 {{jsxref("Object.prototype.toSource")}} 方法。
+
{{jsxref("String.prototype.toString()")}}
+
返回用字符串表示的特定对象。重写 {{jsxref("Object.prototype.toString")}} 方法。
+
{{jsxref("String.prototype.toUpperCase()")}}
+
将字符串转换成大写并返回。
+
{{jsxref("String.prototype.trim()")}}
+
从字符串的开始和结尾去除空格。参照部分 ECMAScript 5 标准。
+
{{jsxref("String.prototype.trimStart()")}}
+
{{jsxref("String.prototype.trimLeft()")}} {{ Non-standard_inline() }}
+
从字符串的左侧去除空格。
+
{{jsxref("String.prototype.trimEnd()")}}
+
{{jsxref("String.prototype.trimRight()")}} {{ Non-standard_inline() }}
+
从字符串的右侧去除空格。
+
{{jsxref("String.prototype.valueOf()")}}
+
返回特定对象的原始值。重写 {{jsxref("Object.prototype.valueOf")}} 方法。
+
{{jsxref("String.prototype.@@iterator()", "String.prototype[@@iterator]()")}}
+
返回一个新的迭代器对象,该对象遍历字符串值的索引位置,将每个索引值作为字符串值返回。
+
+ +

HTML wrapper methods

+ +

下面的方法被限制使用,因为只对可用的HTML标签和属性提供部分支持。

+ +
+
{{jsxref("String.prototype.anchor()")}}
+
<a name="name"> (hypertext target)
+
{{jsxref("String.prototype.big()")}} {{deprecated_inline}}
+
{{HTMLElement("big")}}
+
{{jsxref("String.prototype.blink()")}} {{deprecated_inline}}
+
{{HTMLElement("blink")}}
+
{{jsxref("String.prototype.bold()")}} {{deprecated_inline}}
+
{{HTMLElement("b")}}
+
{{jsxref("String.prototype.fixed()")}} {{deprecated_inline}}
+
{{HTMLElement("tt")}}
+
{{jsxref("String.prototype.fontcolor()")}} {{deprecated_inline}}
+
<font color="color">
+
{{jsxref("String.prototype.fontsize()")}} {{deprecated_inline}}
+
<font size="size">
+
{{jsxref("String.prototype.italics()")}} {{deprecated_inline}}
+
{{HTMLElement("i")}}
+
{{jsxref("String.prototype.link()")}}
+
<a href="url"> (link to URL)
+
{{jsxref("String.prototype.small()")}} {{deprecated_inline}}
+
{{HTMLElement("small")}}
+
{{jsxref("String.prototype.strike()")}} {{deprecated_inline}}
+
{{HTMLElement("strike")}}
+
{{jsxref("String.prototype.sub()")}} {{deprecated_inline}}
+
{{HTMLElement("sub")}}
+
{{jsxref("String.prototype.sup()")}} {{deprecated_inline}}
+
{{HTMLElement("sup")}}
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.5.3.1', 'String.prototype')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.prototype")}}

+ +

更多

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/quote/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/quote/index.html new file mode 100644 index 0000000000..3d8d197f46 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/quote/index.html @@ -0,0 +1,116 @@ +--- +title: String.prototype.quote() +slug: Web/JavaScript/Reference/Global_Objects/String/quote +tags: + - JavaScript + - Method + - Non-standard + - Obsolete + - Prototype + - String +translation_of: Archive/Web/JavaScript/String.quote +--- +
{{obsolete_header("37")}}
+ +
{{JSRef("Global_Objects", "String")}}{{Non-standard_header}}
+ +

概述

+ +

将字符串中包含的特殊字符进行转义(反斜杠),然后在字符串两边各加上一个双引号(")并返回,并不修改原字符串.

+ +

语法

+ +
str.quote()
+ +

示例

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
strstr.quote()eval(str.quote())
Hello world!"Hello world!"Hello world!
Hello
+         world!
"Hello\n\tworld!"Hello
+         world!
" \ — '"\" \\ \u2014 '"" \ — '
+ +

规范

+ +

不在任何规范中。实现于 JavaScript 1.3.

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/raw/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/raw/index.html new file mode 100644 index 0000000000..89c4d568d5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/raw/index.html @@ -0,0 +1,113 @@ +--- +title: String.raw() +slug: Web/JavaScript/Reference/Global_Objects/String/raw +tags: + - JavaScript + - Method + - Reference + - String + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/raw +--- +
{{JSRef()}}
+ +

String.raw() 是一个模板字符串的标签函数,它的作用类似于 Python 中的字符串前缀 r 和 C# 中的字符串前缀 @(还是有点区别的,详见隔壁 Chromium 那边的这个 issue),是用来获取一个模板字符串的原始字符串的,比如说,占位符(例如 ${foo})会被处理为它所代表的其他字符串,而转义字符(例如 \n)不会。

+ +

语法

+ +
String.raw(callSite, ...substitutions)
+
+String.raw`templateString`
+
+ +

参数

+ +
+
callSite
+
一个模板字符串的“调用点对象”。类似{ raw: ['foo', 'bar', 'baz'] }
+
...substitutions
+
任意个可选的参数,表示任意个内插表达式对应的值。
+
templateString
+
模板字符串,可包含占位符(${...})。
+
+ +

返回值

+ +

给定模板字符串的原始字符串。

+ +

异常

+ +
+
{{jsxref("TypeError")}}
+
如果第一个参数没有传入一个格式正确的对象,则会抛出 TypeError 异常。
+
+ +

描述

+ +

在大多数情况下, String.raw()是用来处理模版字符串的. 不要被上面复杂的参数要求吓到,因为像所有的 tag functions一样,你通常不需要把它看成一个普通函数,你只需要把它放在模板字符串前面就可以了,而不是在它后面加个括号和一堆参数来调用它,引擎会替你去调用它。

+ +

String.raw() 是唯一一个内置的模板字符串标签函数,因为它太常用了。不过它并没有什么特殊能力,你自己也可以实现一个和它功能一模一样的标签函数。

+ +

示例

+ +

使用 String.raw()

+ +
String.raw`Hi\n${2+3}!`;
+// 'Hi\n5!',Hi 后面的字符不是换行符,\ 和 n 是两个不同的字符
+
+String.raw `Hi\u000A!`;
+// "Hi\u000A!",同上,这里得到的会是 \、u、0、0、0、A 6个字符,
+// 任何类型的转义形式都会失效,保留原样输出,不信你试试.length
+
+let name = "Bob";
+String.raw `Hi\n${name}!`;
+// "Hi\nBob!",内插表达式还可以正常运行
+
+
+// 正常情况下,你也许不需要将 String.raw() 当作函数调用。
+// 但是为了模拟 `t${0}e${1}s${2}t` 你可以这样做:
+String.raw({ raw: 'test' }, 0, 1, 2); // 't0e1s2t'
+// 注意这个测试, 传入一个 string, 和一个类似数组的对象
+// 下面这个函数和 `foo${2 + 3}bar${'Java' + 'Script'}baz` 是相等的.
+String.raw({
+  raw: ['foo', 'bar', 'baz']
+}, 2 + 3, 'Java' + 'Script'); // 'foo5barJavaScriptbaz'
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-string.raw', 'String.raw')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-string.raw', 'String.raw')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.raw")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/repeat/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/repeat/index.html new file mode 100644 index 0000000000..ce35065f1a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/repeat/index.html @@ -0,0 +1,124 @@ +--- +title: String.prototype.repeat() +slug: Web/JavaScript/Reference/Global_Objects/String/repeat +tags: + - ECMAScript 2015 + - ES 6 + - JavaScript + - Method + - Prototype + - Reference + - String + - polyfill + - repeat() + - 填充 +translation_of: Web/JavaScript/Reference/Global_Objects/String/repeat +--- +

{{JSRef}}

+ +

repeat() 构造并返回一个新字符串,该字符串包含被连接在一起的指定数量的字符串的副本。

+ +

语法

+ +
str.repeat(count)
+ +

参数

+ +
+
count
+
介于 0 和 {{jsxref("Global_Objects/Number/POSITIVE_INFINITY", "+Infinity")}} 之间的整数。表示在新构造的字符串中重复了多少遍原字符串。
+
+ +

返回值

+ +

 包含指定字符串的指定数量副本的新字符串。

+ +

Exceptions

+ + + +

兼容补丁(Polyfill)

+ +

此方法已添加到 ECMAScript 2015 规范中,并且可能尚未在所有 JavaScript 实现中可用。然而,你可以使用以下代码段对 String.prototype.repeat() 进行填充:

+ +
if (!String.prototype.repeat) {
+  String.prototype.repeat = function(count) {
+    'use strict';
+    if (this == null) {
+      throw new TypeError('can\'t convert ' + this + ' to object');
+    }
+    var str = '' + this;
+    count = +count;
+    if (count != count) {
+      count = 0;
+    }
+    if (count < 0) {
+      throw new RangeError('repeat count must be non-negative');
+    }
+    if (count == Infinity) {
+      throw new RangeError('repeat count must be less than infinity');
+    }
+    count = Math.floor(count);
+    if (str.length == 0 || count == 0) {
+      return '';
+    }
+    // 确保 count 是一个 31 位的整数。这样我们就可以使用如下优化的算法。
+    // 当前(2014年8月),绝大多数浏览器都不能支持 1 << 28 长的字符串,所以:
+    if (str.length * count >= 1 << 28) {
+      throw new RangeError('repeat count must not overflow maximum string size');
+    }
+    var rpt = '';
+    for (;;) {
+      if ((count & 1) == 1) {
+        rpt += str;
+      }
+      count >>>= 1;
+      if (count == 0) {
+        break;
+      }
+      str += str;
+    }
+    return rpt;
+  }
+}
+ + +

示例

+ +
"abc".repeat(-1)     // RangeError: repeat count must be positive and less than inifinity
+"abc".repeat(0)      // ""
+"abc".repeat(1)      // "abc"
+"abc".repeat(2)      // "abcabc"
+"abc".repeat(3.5)    // "abcabcabc" 参数count将会被自动转换成整数.
+"abc".repeat(1/0)    // RangeError: repeat count must be positive and less than inifinity
+
+({toString : () => "abc", repeat : String.prototype.repeat}).repeat(2)
+//"abcabc",repeat是一个通用方法,也就是它的调用者可以不是一个字符串对象.
+ +

规范

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-string.prototype.repeat', 'String.prototype.repeat')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.String.repeat")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/replace/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/replace/index.html new file mode 100644 index 0000000000..c4d8f758cb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/replace/index.html @@ -0,0 +1,317 @@ +--- +title: String.prototype.replace() +slug: Web/JavaScript/Reference/Global_Objects/String/replace +tags: + - JavaScript + - Method + - Prototype + - Regular + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/replace +--- +
{{JSRef}}
+ +

replace() 方法返回一个由替换值(replacement)替换部分或所有的模式(pattern)匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。如果pattern是字符串,则仅替换第一个匹配项。

+ +

原字符串不会改变。

+ +
{{EmbedInteractiveExample("pages/js/string-replace.html")}}
+ + + +

语法

+ +
str.replace(regexp|substr, newSubStr|function)
+ +

参数

+ +
+
regexp (pattern)
+
一个{{jsxref("RegExp")}} 对象或者其字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。
+
+ +
+
substr (pattern)
+
一个将被 newSubStr 替换的 {{jsxref("String","字符串")}}。其被视为一整个字符串,而不是一个正则表达式。仅第一个匹配项会被替换。
+
+ +
+
newSubStr (replacement)
+
用于替换掉第一个参数在原字符串中的匹配部分的{{jsxref("String", "字符串")}}。该字符串中可以内插一些特殊的变量名。参考下面的使用字符串作为参数
+
+ +
+
function (replacement)
+
一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。参考下面的指定一个函数作为参数
+
+ +

返回值

+ +

一个部分或全部匹配由替代模式所取代的新的字符串。

+ +

描述

+ +

该方法并不改变调用它的字符串本身,而只是返回一个新的替换后的字符串。

+ +

在进行全局的搜索替换时,正则表达式需包含 g 标志。

+ +

使用字符串作为参数

+ +

替换字符串可以插入下面的特殊变量名:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
变量名代表的值
$$插入一个 "$"。
$&插入匹配的子串。
$`插入当前匹配的子串左边的内容。
$'插入当前匹配的子串右边的内容。
$n +

假如第一个参数是 {{jsxref("RegExp")}}对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。提示:索引是从1开始。如果不存在第 n个分组,那么将会把匹配到到内容替换为字面量。比如不存在第3个分组,就会用“$3”替换匹配到的内容。

+
$<Name> 这里Name 是一个分组名称。如果在正则表达式中并不存在分组(或者没有匹配),这个变量将被处理为空字符串。只有在支持命名分组捕获的浏览器中才能使用。
+ +

指定一个函数作为参数

+ +

你可以指定一个函数作为第二个参数。在这种情况下,当匹配执行后,该函数就会执行。 函数的返回值作为替换字符串。 (注意:上面提到的特殊替换参数在这里不能被使用。) 另外要注意的是,如果第一个参数是正则表达式,并且其为全局匹配模式,那么这个方法将被多次调用,每次匹配都会被调用。

+ +

下面是该函数的参数:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
变量名代表的值
match匹配的子串。(对应于上述的$&。)
p1,p2, ... +

假如replace()方法的第一个参数是一个{{jsxref("RegExp")}} 对象,则代表第n个括号匹配的字符串。(对应于上述的$1,$2等。)例如,如果是用 /(\a+)(\b+)/ 这个来匹配,p1 就是匹配的 \a+p2 就是匹配的 \b+

+
offset +

匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是 'abcd',匹配到的子字符串是 'bc',那么这个参数将会是 1)

+
string被匹配的原字符串。
NamedCaptureGroup命名捕获组匹配的对象
+ +

(精确的参数个数依赖于 replace() 的第一个参数是否是一个正则表达式({{jsxref("RegExp")}})对象,以及这个正则表达式中指定了多少个括号子串,如果这个正则表达式里使用了命名捕获, 还会添加一个命名捕获的对象)

+ +

下面的例子将会使 newString 变成 'abc - 12345 - #$*%'

+ +
function replacer(match, p1, p2, p3, offset, string) {
+  // p1 is nondigits, p2 digits, and p3 non-alphanumerics
+  return [p1, p2, p3].join(' - ');
+}
+var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
+console.log(newString);  // abc - 12345 - #$*%
+
+ +

示例

+ +

replace() 中使用正则表达式

+ +

在下面的例子中,replace() 中使用了正则表达式及忽略大小写标示。

+ +
var str = 'Twas the night before Xmas...';
+var newstr = str.replace(/xmas/i, 'Christmas');
+console.log(newstr);  // Twas the night before Christmas...
+
+ +

replace() 中使用 globalignore 选项

+ +

下面的例子中,正则表达式包含有全局替换(g)和忽略大小写(i)的选项,这使得replace方法用'oranges'替换掉了所有出现的"apples".

+ +
var re = /apples/gi;
+var str = "Apples are round, and apples are juicy.";
+var newstr = str.replace(re, "oranges");
+
+// oranges are round, and oranges are juicy.
+console.log(newstr);
+
+ +

交换字符串中的两个单词

+ +

下面的例子演示了如何交换一个字符串中两个单词的位置,这个脚本使用$1 和 $2 代替替换文本。

+ +
var re = /(\w+)\s(\w+)/;
+var str = "John Smith";
+var newstr = str.replace(re, "$2, $1");
+// Smith, John
+console.log(newstr);
+
+ +

使用行内函数来修改匹配到的字符。

+ +

在这个例子中,所有出现的大写字母转换为小写,并且在匹配位置前加一个连字符。重要的是,在返回一个替换了的字符串前,在匹配元素前进行添加操作是必要的。

+ +

在返回前,替换函数允许匹配片段作为参数,并且将它和连字符进行连接作为新的片段。

+ +
function styleHyphenFormat(propertyName) {
+  function upperToHyphenLower(match) {
+    return '-' + match.toLowerCase();
+  }
+  return propertyName.replace(/[A-Z]/g, upperToHyphenLower);
+}
+
+ +

运行 styleHyphenFormat('borderTop')返回 'border-top'。

+ +

因为我们想在最终的替换中进一步转变匹配结果,所以我们必须使用一个函数。这迫使我们在使用{{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}}方法前进行评估。如果我们尝试不用一个函数进行匹配,那么使用{{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}} 方法将不会有效。

+ +
var newString = propertyName.replace(/[A-Z]/g, '-' + '$&'.toLowerCase());  // won't work
+
+ +

这是因为 '$&'.toLowerCase() 会先被解析成字符串字面量(这会导致相同的'$&')而不是当作一个模式。

+ +

将华氏温度转换为对等的摄氏温度

+ +

下面的例子演示如何将华氏温度转换为对等的摄氏温度。华氏温度用一个数字加一个"F"来表示,这个函数将返回一个数字加"C"来表示的摄氏温度。例如,如果输入是 212F,这个函数将返回 100C。如果输入的数字是 0F,这个方法将返回 "-17.77777777777778C"。

+ +

正则表达式test检查任何数字是否以 F 结尾。华氏温度通过第二个参数p1进入函数。这个函数基于华氏温度作为字符串传递给f2c函数设置成摄氏温度。然后f2c()返回摄氏温度。这个函数与Perl的 s///e 标志相似。

+ +
function f2c(x)
+{
+  function convert(str, p1, offset, s)
+  {
+    return ((p1-32) * 5/9) + "C";
+  }
+  var s = String(x);
+  var test = /(\d+(?:\.\d*)?)F\b/g;
+  return s.replace(test, convert);
+}
+
+ +

使用行内函数和正则来避免循环

+ +

下例把某种模式的字符串转换为一个对象数组(其元素为对象)。

+ +

输入:
+ 一个由 x,- 和 _ 组成的字符串。

+ +
x-x_
+
+---x---x---x---
+
+-xxx-xx-x-
+
+_x_x___x___x___
+
+ +

输出:

+ +

一个数组对象。'x' 产生一个 'on' 状态,'-'(连接符)产生一个 'off' 状态,而 '_' (下划线)表示 'on' 状态的长度。

+ +
[
+  { on: true, length: 1 },
+  { on: false, length: 1 },
+  { on: true, length: 2 }
+  ...
+]
+ +

代码片段:

+ +
var str = 'x-x_';
+var retArr = [];
+str.replace(/(x_*)|(-)/g, function(match, p1, p2) {
+  if (p1) { retArr.push({ on: true, length: p1.length }); }
+  if (p2) { retArr.push({ on: false, length: 1 }); }
+});
+
+console.log(retArr);
+ +

该代码片段生成了一个数组,包含三个期望格式的对象,避免了使用 for 循环语句。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.5.4.11', 'String.prototype.replace')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.replace', 'String.prototype.replace')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype.replace', 'String.prototype.replace')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.replace")}}

+ +

Firefox 备注

+ + + +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/replaceall/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/replaceall/index.html new file mode 100644 index 0000000000..b79277e488 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/replaceall/index.html @@ -0,0 +1,171 @@ +--- +title: String.prototype.replaceAll() +slug: Web/JavaScript/Reference/Global_Objects/String/replaceAll +tags: + - global flag / g + - replace + - replaceAll +translation_of: Web/JavaScript/Reference/Global_Objects/String/replaceAll +--- +
{{JSRef}}
+ +

replaceAll() 方法返回一个新字符串,新字符串所有满足 pattern 的部分都已被replacement 替换。pattern可以是一个字符串或一个 {{jsxref("RegExp")}}, replacement可以是一个字符串或一个在每次匹配被调用的函数。

+ +

原始字符串保持不变。

+ +
{{EmbedInteractiveExample("pages/js/string-replaceall.html")}}
+ + + +

语法

+ +
const newStr = str.replaceAll(regexp|substr, newSubstr|function)
+ +
+

当使用一个 `regex`时,您必须设置全局(“ g”)标志,
+ 否则,它将引发 TypeError:“必须使用全局 RegExp 调用 replaceAll”。

+
+ +

参数

+ +
+
regexp (pattern)
+
A {{jsxref("RegExp")}} object or literal with the global flag. The matches are replaced with newSubstr or the value returned by the specified function. A RegExp without the global ("g") flag will throw a TypeError: "replaceAll must be called with a global RegExp".
+
substr
+
A {{jsxref("String")}} that is to be replaced by newSubstr. It is treated as a literal string and is not interpreted as a regular expression.
+
newSubstr (replacement)
+
The {{jsxref("String")}} that replaces the substring specified by the specified regexp or substr parameter. A number of special replacement patterns are supported; see the "Specifying a string as a parameter" section below.
+
function (replacement)
+
A function to be invoked to create the new substring to be used to replace the matches to the given regexp or substr. The arguments supplied to this function are described in the "Specifying a function as a parameter" section below.
+
+ +

返回值

+ +

A new string, with all matches of a pattern replaced by a replacement.

+ +

描述

+ +

此方法不会更改调用 {{jsxref("String")}} 对象。它只是返回一个新字符串。

+ +

将一个字符串作为一个参数

+ +

The replacement string can include the following special replacement patterns:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PatternInserts
$$Inserts a "$".
$&Inserts the matched substring.
$`Inserts the portion of the string that precedes the matched substring.
$'Inserts the portion of the string that follows the matched substring.
$nWhere n is a positive integer less than 100, inserts the nth parenthesized submatch string, provided the first argument was a {{jsxref("RegExp")}} object. Note that this is 1-indexed.
+ +

将一个函数指定为一个参数

+ +

你可以指定一个函数作为第二个参数,在这种情况下,函数只有在匹配发生之后才会被调用。The function's result (return value) will be used as the replacement string. (Note: The above-mentioned special replacement patterns do not apply in this case.)

+ +

Note that the function will be invoked multiple times for each full match to be replaced if the regular expression in the first parameter is global.

+ +

The arguments to the function are as follows:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Possible nameSupplied value
matchThe matched substring. (Corresponds to $& above.)
p1, p2, ...The nth string found by a parenthesized capture group, provided the first argument to replace() was a {{jsxref("RegExp")}} object. (Corresponds to $1, $2, etc. above.) For example, if /(\a+)(\b+)/, was given, p1 is the match for \a+, and p2 for \b+.
offsetThe offset of the matched substring within the whole string being examined. (For example, if the whole string was 'abcd', and the matched substring was 'bc', then this argument will be 1.)
stringThe whole string being examined.
+ +

(The exact number of arguments depends on whether the first argument is a {{jsxref("RegExp")}} object—and, if so, how many parenthesized submatches it specifies.)

+ +

例子

+ +

使用 replaceAll

+ +
'aabbcc'.replaceAll('b', '.');
+// 'aa..cc'
+ +

非全局 regex 抛出

+ +

使用正则表达式搜索值时,它必须是全局的。这将行不通:

+ +
'aabbcc'.replaceAll(/b/, '.');
+TypeError: replaceAll must be called with a global RegExp
+
+ +

这将可以正常运行:

+ +
'aabbcc'.replaceAll(/b/g, '.');
+"aa..cc"
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-string.prototype.replaceall', 'String.prototype.replaceAll')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.replaceAll")}}

+ +

了解更多

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/search/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/search/index.html new file mode 100644 index 0000000000..66ab981508 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/search/index.html @@ -0,0 +1,87 @@ +--- +title: String.prototype.search() +slug: Web/JavaScript/Reference/Global_Objects/String/search +tags: + - JavaScript + - 原型 + - 参考 + - 字符串 + - 方法 + - 正则表达式 +translation_of: Web/JavaScript/Reference/Global_Objects/String/search +--- +
{{JSRef}}
+ +

search() 方法执行正则表达式和 {{jsxref("String")}} 对象之间的一个搜索匹配。

+ +
{{EmbedInteractiveExample("pages/js/string-search.html")}}
+ + + +

语法

+ +
str.search(regexp)
+ +

参数

+ +
+
regexp
+
一个{{jsxref("RegExp", "正则表达式(regular expression)")}}对象
+
如果传入一个非正则表达式对象 regexp,则会使用 new RegExp(regexp) 隐式地将其转换为正则表达式对象。
+
+ +

返回值

+ +

如果匹配成功,则 search() 返回正则表达式在字符串中首次匹配项的索引;否则,返回 -1

+ +

描述

+ +

当你想要知道字符串中是否存在某个模式(pattern)时可使用 search(),类似于正则表达式的 {{jsxref("RegExp.test", "test()")}} 方法。当要了解更多匹配信息时,可使用 {{jsxref("String.match", "match()")}}(但会更慢一些),该方法类似于正则表达式的 {{jsxref("RegExp.exec", "exec()")}} 方法。

+ +

示例

+ + + +

下面的例子中用两个不同的正则表达式对同一个字符串执行搜索匹配,得到一个成功匹配(正数返回值)和一个失败匹配(-1)。

+ +
var str = "hey JudE";
+var re = /[A-Z]/g;
+var re2 = /[.]/g;
+console.log(str.search(re)); // returns 4, which is the index of the first capital letter "J"
+console.log(str.search(re2)); // returns -1 cannot find '.' dot punctuation
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-string.prototype.search', 'String.prototype.search')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.search")}}

+ +

Gecko 注意事项

+ + + +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/slice/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/slice/index.html new file mode 100644 index 0000000000..df8f398983 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/slice/index.html @@ -0,0 +1,122 @@ +--- +title: String.prototype.slice() +slug: Web/JavaScript/Reference/Global_Objects/String/slice +tags: + - JavaScript + - Method + - Prototype + - String + - 原型 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/slice +--- +
{{JSRef}}
+ +

slice() 方法提取某个字符串的一部分,并返回一个新的字符串,且不会改动原字符串。

+ +
{{EmbedInteractiveExample("pages/js/string-slice.html")}}
+ + + +

语法

+ +
str.slice(beginIndex[, endIndex])
+ +

参数

+ +
+
beginIndex
+
从该索引(以 0 为基数)处开始提取原字符串中的字符。如果值为负数,会被当做 strLength + beginIndex 看待,这里的strLength 是字符串的长度(例如, 如果 beginIndex 是 -3 则看作是:strLength - 3
+
endIndex
+
可选。在该索引(以 0 为基数)处结束提取字符串。如果省略该参数,slice() 会一直提取到字符串末尾。如果该参数为负数,则被看作是 strLength + endIndex,这里的 strLength 就是字符串的长度(例如,如果 endIndex 是 -3,则是, strLength - 3)。
+
+ +

返回值

+ +

返回一个从原字符串中提取出来的新字符串

+ +

描述

+ +

slice() 从一个字符串中提取字符串并返回新字符串。在一个字符串中的改变不会影响另一个字符串。也就是说,slice 不会修改原字符串(只会返回一个包含了原字符串中部分字符的新字符串)。

+ +

slice() 提取的新字符串包括beginIndex但不包括 endIndex。下面有两个例子。

+ +

例 1:str.slice(1, 4) 提取第二个字符到第四个字符(被提取字符的索引值(index)依次为 1、2,和 3)。

+ +

例 2:str.slice(2, -1) 提取第三个字符到倒数第一个字符。

+ +

例子

+ +

使用 slice() 创建一个新的字符串

+ +

下面例子使用 slice() 创建了一个新字符串。

+ +
var str1 = 'The morning is upon us.', // str1 的长度 length 是 23。
+    str2 = str1.slice(1, 8),
+    str3 = str1.slice(4, -2),
+    str4 = str1.slice(12),
+    str5 = str1.slice(30);
+console.log(str2); // 输出:he morn
+console.log(str3); // 输出:morning is upon u
+console.log(str4); // 输出:is upon us.
+console.log(str5); // 输出:""
+
+ +

给 slice() 传入负值索引

+ +

下面的例子在使用 slice() 时传入了负值作为索引。

+ +
var str = 'The morning is upon us.';
+str.slice(-3);     // 返回 'us.'
+str.slice(-3, -1); // 返回 'us'
+str.slice(0, -1);  // 返回 'The morning is upon us'
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-string.prototype.slice', 'String.prototype.slice')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-string.prototype.slice', 'String.prototype.slice')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-15.5.4.13', 'String.prototype.slice')}}{{Spec2('ES5.1')}}
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.slice")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/small/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/small/index.html new file mode 100644 index 0000000000..7b55c68248 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/small/index.html @@ -0,0 +1,119 @@ +--- +title: String.prototype.small() +slug: Web/JavaScript/Reference/Global_Objects/String/small +translation_of: Web/JavaScript/Reference/Global_Objects/String/small +--- +
{{JSRef}} {{deprecated_header}}
+ +

small() 方法的作用是创建一个使字符串显示小号字体的 {{HTMLElement("small")}} 标签。

+ +

语法

+ +
str.small()
+ +

返回值

+ +

带有 {{HTMLElement("small")}} 标签的字符串。

+ +

描述

+ +

small() 方法会 将一个字符串嵌入到<small> 标签中: "<small>str</small>"。

+ +

示例

+ +

使用small()函数

+ +

为了改变一个字符串的字体大小,下面的例子使用了字符串中的方法:

+ +
var worldString = 'Hello, world';
+
+console.log(worldString.small());     // <small>Hello, world</small>
+console.log(worldString.big());       // <big>Hello, world</big>
+console.log(worldString.fontsize(7)); // <font size="7">Hello, world</fontsize>
+
+ +

使用{{domxref("HTMLElement.style", "element.style")}}对象,你能更加一般地获得和操作该元素的属性,比如:

+ +
document.getElementById('yourElemId').style.fontSize = '0.7em';
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.small', 'String.prototype.small')}}{{Spec2('ES6')}}初始定义。 在JavaScript 1.0中实现。在(规范性)附件B中定义了用于Web浏览器的附加ECMAScript 特性。
{{SpecName('ESDraft', '#sec-string.prototype.small', 'String.prototype.small')}}{{Spec2('ESDraft')}}在(规范性)附件B中定义了用于Web浏览器的附加ECMAScript 特性。
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/split/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/split/index.html new file mode 100644 index 0000000000..c1dee44c87 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/split/index.html @@ -0,0 +1,213 @@ +--- +title: String.prototype.split() +slug: Web/JavaScript/Reference/Global_Objects/String/split +tags: + - JavaScript + - Method + - Prototype + - Reference + - Regular Expressions + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/split +--- +

{{JSRef}}

+ +

split() 方法使用指定的分隔符字符串将一个{{jsxref("String")}}对象分割成子字符串数组,以一个指定的分割字串来决定每个拆分的位置。 

+ +
{{EmbedInteractiveExample("pages/js/string-split.html")}}
+ + + +

语法

+ +
str.split([separator[, limit]])
+
+ +
+

注意:如果使用空字符串(“)作为分隔符,则字符串不是在每个用户感知的字符(图形素集群)之间,也不是在每个Unicode字符(代码点)之间,而是在每个UTF-16代码单元之间。这会摧毁代理对。还请参见how do you get a string to a character array in javascript

+
+ +

参数

+ +
+
separator
+
指定表示每个拆分应发生的点的字符串。separator 可以是一个字符串或正则表达式。 如果纯文本分隔符包含多个字符,则必须找到整个字符串来表示分割点。如果在str中省略或不出现分隔符,则返回的数组包含一个由整个字符串组成的元素。如果分隔符为空字符串,则将str原字符串中每个字符的数组形式返回。
+
limit
+
一个整数,限定返回的分割片段数量。当提供此参数时,split 方法会在指定分隔符的每次出现时分割该字符串,但在限制条目已放入数组时停止。如果在达到指定限制之前达到字符串的末尾,它可能仍然包含少于限制的条目。新数组中不返回剩下的文本。
+
+ +

返回值

+ +

返回源字符串以分隔符出现位置分隔而成的一个 {{jsxref("Array")}} 

+ +

描述

+ +

找到分隔符后,将其从字符串中删除,并将子字符串的数组返回。如果没有找到或者省略了分隔符,则该数组包含一个由整个字符串组成的元素。如果分隔符为空字符串,则将str转换为字符数组。如果分隔符出现在字符串的开始或结尾,或两者都分开,分别以空字符串开头,结尾或两者开始和结束。因此,如果字符串仅由一个分隔符实例组成,则该数组由两个空字符串组成。

+ +

如果分隔符是包含捕获括号的正则表达式,则每次分隔符匹配时,捕获括号的结果(包括任何未定义的结果)将被拼接到输出数组中。但是,并不是所有浏览器都支持此功能。

+ +

{{Note("当字符串为空时,split()返回一个包含一个空字符串的数组,而不是一个空数组,如果字符串和分隔符都是空字符串,则返回一个空数组。")}}

+ +

示例

+ +

使用 split()

+ +

下例定义了一个函数:根据指定的分隔符将一个字符串分割成一个字符串数组。分隔字符串后,该函数依次输出原始字符串信息,被使用的分隔符,返回数组元素的个数,以及返回数组中所有的元素。

+ +
function splitString(stringToSplit, separator) {
+  var arrayOfStrings = stringToSplit.split(separator);
+
+  console.log('The original string is: "' + stringToSplit + '"');
+  console.log('The separator is: "' + separator + '"');
+  console.log("The array has " + arrayOfStrings.length + " elements: ");
+
+  for (var i=0; i < arrayOfStrings.length; i++)
+    console.log(arrayOfStrings[i] + " / ");
+}
+
+var tempestString = "Oh brave new world that has such people in it.";
+var monthString = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec";
+
+var space = " ";
+var comma = ",";
+
+splitString(tempestString, space);
+splitString(tempestString);
+splitString(monthString, comma);
+
+ +

上例输出下面结果:

+ +
The original string is: "Oh brave new world that has such people in it."
+The separator is: " "
+The array has 10 elements: Oh / brave / new / world / that / has / such / people / in / it. /
+
+The original string is: "Oh brave new world that has such people in it."
+The separator is: "undefined"
+The array has 1 elements: Oh brave new world that has such people in it. /
+
+The original string is: "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec"
+The separator is: ","
+The array has 12 elements: Jan / Feb / Mar / Apr / May / Jun / Jul / Aug / Sep / Oct / Nov / Dec /
+
+ +

移出字符串中的空格

+ +

下例中,split() 方法会查找“0 或多个空白符接着的分号,再接着 0 或多个空白符”模式的字符串,找到后,就将空白符从字符串中移除,nameListsplit 的返回数组。

+ +
var names = "Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ;Chris Hand ";
+
+console.log(names);
+
+var re = /\s*(?:;|$)\s*/;
+var nameList = names.split(re);
+
+console.log(nameList);
+
+ +

上例输出两行,第一行输出原始字符串,第二行输出结果数组。

+ +
Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ;Chris Hand
+[ "Harry Trump", "Fred Barney", "Helen Rigby", "Bill Abel", "Chris Hand", "" ]
+
+ +

限制返回值中分割元素数量

+ +

下例中,split 查找字符串中的 0 或多个空格,并返回找到的前 3 个分割元素(splits)。

+ +
var myString = "Hello World. How are you doing?";
+var splits = myString.split(" ", 3);
+
+console.log(splits);
+
+ +

上例输出:

+ +
["Hello", "World.", "How"]
+ +

靠正则来分割使结果中包含分隔块

+ +

如果 separator 包含捕获括号(capturing parentheses),则其匹配结果将会包含在返回的数组中。

+ +
var myString = "Hello 1 word. Sentence number 2.";
+var splits = myString.split(/(\d)/);
+
+console.log(splits);
+
+ +

上例输出:

+ +
[ "Hello ", "1", " word. Sentence number ", "2", "." ]
+ +

使用一个数组来作为分隔符

+ +
const myString = 'this|is|a|Test';
+const splits = myString.split(['|']);
+
+console.log(splits); //["this", "is", "a", "Test"]
+
+const myString = 'ca,bc,a,bca,bca,bc';
+
+const splits = myString.split(['a','b']);
+// myString.split(['a','b']) is same as myString.split(String(['a','b']))
+
+console.log(splits);  //["c", "c,", "c", "c", "c"]
+ +

用split()来颠倒字符串顺序

+ +
+

注意这并非一种很健壮的逆转字符串的方法:

+ +
const str = 'asdfghjkl';
+const strReverse = str.split('').reverse().join(''); // 'lkjhgfdsa'
+// split() returns an array on which reverse() and join() can be applied
+ +

如果字符串包含图形素集群,即使使用Unicode感知的拆分(use for example esrever instead),也不能工作。

+ +
const str = 'résumé';
+const strReverse = str.split(/(?:)/u).reverse().join('');
+// => "́emuśer"
+ +

Bonus: use {{jsxref("Operators/Comparison_Operators", "===", "#Identity_strict_equality_(===)")}} operator to test if the original string was palindrome.

+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 3rd Edition.StandardInitial definition.
+ Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-15.5.4.14', 'String.prototype.split')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.split', 'String.prototype.split')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.String.split")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/startswith/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/startswith/index.html new file mode 100644 index 0000000000..2aaef9b688 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/startswith/index.html @@ -0,0 +1,97 @@ +--- +title: String.prototype.startsWith() +slug: Web/JavaScript/Reference/Global_Objects/String/startsWith +tags: + - JavaScript + - Prototype + - String + - 原型 + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/startsWith +--- +
{{JSRef}}
+ +

startsWith() 方法用来判断当前字符串是否以另外一个给定的子字符串开头,并根据判断结果返回 truefalse

+ +
{{EmbedInteractiveExample("pages/js/string-startswith.html")}}
+ + + +

语法

+ +
str.startsWith(searchString[, position])
+ +

参数

+ +
+
searchString
+
要搜索的子字符串。
+
position {{optional_inline}}
+
str 中搜索 searchString 的开始位置,默认值为 0。
+
+ +

返回值

+ +

如果在字符串的开头找到了给定的字符则返回true;否则返回false

+ +

描述

+ +

这个方法能够让你确定一个字符串是否以另一个字符串开头。这个方法区分大小写。

+ +

Polyfill

+ +

此方法已被添加至 ECMAScript 2015 规范之中,但可能不能在所有的现行 JavaScript 实现中使用。不过,你可以用以下的代码段为 String.prototype.startsWith() 制作 Polyfill:

+ +
if (!String.prototype.startsWith) {
+    Object.defineProperty(String.prototype, 'startsWith', {
+        value: function(search, pos) {
+            pos = !pos || pos < 0 ? 0 : +pos;
+            return this.substring(pos, pos + search.length) === search;
+        }
+    });
+}
+
+ +

Mathias Bynens 在 Github 上提供了一份更为稳定有效(完全符合 ES2015 规范),但性能略差、代码紧凑性微减的 PolyFill

+ +

示例

+ +

使用 startsWith()

+ +
var str = "To be, or not to be, that is the question.";
+
+alert(str.startsWith("To be"));         // true
+alert(str.startsWith("not to be"));     // false
+alert(str.startsWith("not to be", 10)); // true
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-string.prototype.startswith', 'String.prototype.startsWith')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.startsWith")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/strike/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/strike/index.html new file mode 100644 index 0000000000..3e904a9651 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/strike/index.html @@ -0,0 +1,116 @@ +--- +title: String.prototype.strike() +slug: Web/JavaScript/Reference/Global_Objects/String/strike +translation_of: Web/JavaScript/Reference/Global_Objects/String/strike +--- +
{{JSRef}} {{deprecated_header}}
+ +

strike()方法创建{{HTMLElement("strike")}} HTML 元素,使字符串展示为被删除的文本。

+ +

语法

+ +
str.strike()
+ +

返回值

+ +

包含{{HTMLElement("strike")}} HTML 元素的字符串。

+ +

描述

+ +

strike()方法将字符串嵌入<strike>标签: "<strike>str</strike>".

+ +

示例

+ +

使用strike()

+ +

下面的示例使用字符串方法来修改字符串的格式:

+ +
var worldString = 'Hello, world';
+
+console.log(worldString.blink()); // <blink>Hello, world</blink>
+console.log(worldString.bold()); // <b>Hello, world</b>
+console.log(worldString.italics()); // <i>Hello, world</i>
+console.log(worldString.strike()); // <strike>Hello, world</strike>
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.strike', 'String.prototype.strike')}}{{Spec2('ES6')}}初始定义。在 JavaScript 1.0 中实现。 在(规范性)附件 B 中定义为用于 Web 浏览器的 ECMAScript 附加特性。
{{SpecName('ESDraft', '#sec-string.prototype.strike', 'String.prototype.strike')}}{{Spec2('ESDraft')}}在(规范性)附件 B 中定义为用于 Web 浏览器的 ECMAScript 附加特性。
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/sub/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/sub/index.html new file mode 100644 index 0000000000..8c47471d25 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/sub/index.html @@ -0,0 +1,119 @@ +--- +title: String.prototype.sub() +slug: Web/JavaScript/Reference/Global_Objects/String/sub +tags: + - String.sub() + - 已废弃 +translation_of: Web/JavaScript/Reference/Global_Objects/String/sub +--- +
{{JSRef}} {{deprecated_header}}
+ +

sub()方法创建一个 {{HTMLElement("sub")}} HTML 元素,使字符串展示为下标。

+ +

语法

+ +
str.sub()
+ +

返回值

+ +

包含{{HTMLElement("sub")}} HTML 元素的字符串。

+ +

描述

+ +

sub()方法将字符串嵌入<sub>标签: "<sub>str</sub>".

+ +

示例

+ +

使用sub()sup()方法

+ +

下面的示例使用了sub()和{{jsxref("String.prototype.sup()", "sup()")}}方法来格式化字符串:

+ +
var superText = 'superscript';
+var subText = 'subscript';
+
+console.log('This is what a ' + superText.sup() + ' looks like.');
+// 这就是<sup>superscript</sup>的样子。
+
+console.log('This is what a ' + subText.sub() + ' looks like.');
+// 这就是<sub>subscript</sub>的样子。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.sub', 'String.prototype.sub')}}{{Spec2('ES6')}}初始定义。在 JavaScript 1.0 中实现。在(规范性)附件 B 中定义为用于 Web 浏览器的 ECMAScript 附加特性。
{{SpecName('ESDraft', '#sec-string.prototype.sub', 'String.prototype.sub')}}{{Spec2('ESDraft')}}在(规范性)附件 B 中定义为用于 Web 浏览器的 ECMAScript 附加特性。
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/substr/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/substr/index.html new file mode 100644 index 0000000000..8faa458218 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/substr/index.html @@ -0,0 +1,166 @@ +--- +title: String.prototype.substr() +slug: Web/JavaScript/Reference/Global_Objects/String/substr +tags: + - String.prototype.substr() +translation_of: Web/JavaScript/Reference/Global_Objects/String/substr +--- +

{{JSRef}}

+ +
警告: 尽管 String.prototype.substr(…) 没有严格被废弃 (as in "removed from the Web standards"), 但它被认作是遗留的函数并且可以的话应该避免使用。它并非JavaScript核心语言的一部分,未来将可能会被移除掉。如果可以的话,使用 substring() 替代它.
+ +

substr() 方法返回一个字符串中从指定位置开始到指定字符数的字符。

+ +

语法

+ +
str.substr(start[, length])
+ +

参数

+ +
+
start
+
开始提取字符的位置。如果为负值,则被看作 strLength + start,其中 strLength 为字符串的长度(例如,如果 start-3,则被看作 strLength + (-3))。
+
+ +
+
length
+
可选。提取的字符数。
+
+ +

描述

+ +

start 是一个字符的索引。首字符的索引为 0,最后一个字符的索引为 字符串的长度减去1。substrstart 位置开始提取字符,提取 length 个字符(或直到字符串的末尾)。

+ +

如果 start 为正值,且大于或等于字符串的长度,则 substr 返回一个空字符串。

+ +

如果 start 为负值,则 substr 把它作为从字符串末尾开始的一个字符索引。如果 start 为负值且 abs(start) 大于字符串的长度,则 substr 使用 0 作为开始提取的索引。注意负的 start 参数不被 Microsoft JScript 所支持。

+ +

如果 length 为 0 或负值,则 substr 返回一个空字符串。如果忽略 length,则 substr 提取字符,直到字符串末尾。

+ +

示例

+ +

例子:使用 substr

+ +
var str = "abcdefghij";
+
+console.log("(1,2): "    + str.substr(1,2));   // (1,2): bc
+console.log("(-3,2): "   + str.substr(-3,2));  // (-3,2): hi
+console.log("(-3): "     + str.substr(-3));    // (-3): hij
+console.log("(1): "      + str.substr(1));     // (1): bcdefghij
+console.log("(-20, 2): " + str.substr(-20,2)); // (-20, 2): ab
+console.log("(20, 2): "  + str.substr(20,2));  // (20, 2):
+
+ +

兼容旧环境(Polyfill)

+ +

Microsoft's JScript 不支持负的 start 索引。如果你想充分利用该方法的功能,则需要使用下面的兼容性代码修复此 bug:

+ +
// only run when the substr function is broken
+if ('ab'.substr(-1) != 'b')
+{
+  /**
+   *  Get the substring of a string
+   *  @param  {integer}  start   where to start the substring
+   *  @param  {integer}  length  how many characters to return
+   *  @return {string}
+   */
+  String.prototype.substr = function(substr) {
+    return function(start, length) {
+      // did we get a negative start, calculate how much it is
+      // from the beginning of the string
+      if (start < 0) start = this.length + start;
+
+      // call the original function
+      return substr.call(this, start, length);
+    }
+  }(String.prototype.substr);
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 3rd Edition.StandardDefined in the (informative) Compatibility Annex B.
+ Implemented in JavaScript 1.0
{{SpecName('ES5.1', '#sec-B.2.3', 'String.prototype.substr')}}{{Spec2('ES5.1')}}Defined in the (informative) Compatibility Annex B
{{SpecName('ES6', '#sec-string.prototype.substr', 'String.prototype.substr')}}{{Spec2('ES6')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Note: Up to version 3.6, Firefox had a bug which caused substr to return empty result when an explicit undefined value was passed in as the length.

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/substring/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/substring/index.html new file mode 100644 index 0000000000..9a2d97f935 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/substring/index.html @@ -0,0 +1,194 @@ +--- +title: String.prototype.substring() +slug: Web/JavaScript/Reference/Global_Objects/String/substring +tags: + - String.prototype.substring() +translation_of: Web/JavaScript/Reference/Global_Objects/String/substring +--- +

{{JSRef}}

+ +

substring() 方法返回一个字符串在开始索引到结束索引之间的一个子集, 或从开始索引直到字符串的末尾的一个子集。

+ +

语法

+ +
str.substring(indexStart[, indexEnd])
+ +

参数

+ +
+
indexStart
+
需要截取的第一个字符的索引,该索引位置的字符作为返回的字符串的首字母。
+
indexEnd
+
可选。一个 0 到字符串长度之间的整数,以该数字为索引的字符不包含在截取的字符串内。
+
+ +

返回值

+ +

包含给定字符串的指定部分的新字符串。

+ +

描述

+ +

substring 提取从 indexStart 到 indexEnd(不包括)之间的字符。特别地:

+ + + +

示例

+ +

例子:使用 substring

+ +

下例使用 substring 输出字符串 "Mozilla" 中的字符:

+ +
var anyString = "Mozilla";
+
+// 输出 "Moz"
+console.log(anyString.substring(0,3));
+console.log(anyString.substring(3,0));
+console.log(anyString.substring(3,-3));
+console.log(anyString.substring(3,NaN));
+console.log(anyString.substring(-2,3));
+console.log(anyString.substring(NaN,3));
+
+// 输出 "lla"
+console.log(anyString.substring(4,7));
+console.log(anyString.substring(7,4));
+
+// 输出 ""
+console.log(anyString.substring(4,4));
+
+// 输出 "Mozill"
+console.log(anyString.substring(0,6));
+
+// 输出 "Mozilla"
+console.log(anyString.substring(0,7));
+console.log(anyString.substring(0,10));
+
+ +

运用 length 属性来使用 substring()

+ +

下面一个例子运用了    String.length 属性去获取指定字符串的倒数元素。显然这个办法更容易记住,因为你不再像上面那个例子那样去记住起始位置和最终位置。

+ +
// Displays 'illa' the last 4 characters
+var anyString = 'Mozilla';
+var anyString4 = anyString.substring(anyString.length - 4);
+console.log(anyString4);
+
+// Displays 'zilla' the last 5 characters
+var anyString = 'Mozilla';
+var anyString5 = anyString.substring(anyString.length - 5);
+console.log(anyString5);
+ +

例子:替换一个字符串的子字符串

+ +

下例替换了一个字符串中的子字符串。可以替换单个字符和子字符串。该例结尾调用的函数将 "Brave New World" 变成了 "Brave New Web"。

+ +
function replaceString(oldS, newS, fullS) {
+// Replaces oldS with newS in the string fullS
+  for (var i = 0; i < fullS.length; i++) {
+    if (fullS.substring(i, i + oldS.length) == oldS) {
+     fullS = fullS.substring(0, i) + newS + fullS.substring(i + oldS.length, fullS.length);
+    }
+  }
+  return fullS;
+}
+
+replaceString("World", "Web", "Brave New World");
+ +

需要注意的是,如果 oldSnewS 的子字符串将会导致死循环。例如,尝试把 "Web" 替换成 "OtherWorld"。一个更好的方法如下:

+ +
function replaceString(oldS, newS,fullS){
+  return fullS.split(oldS).join(newS);
+}
+ +

上面的代码只是子字符串操作的一个例子。如果你需要替换子字符串,更多时候会用到 {{jsxref("String.prototype.replace()")}}。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardImplemented in JavaScript 1.0
{{SpecName('ES5.1', '#sec-15.5.4.15', 'String.prototype.substring')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.substring', 'String.prototype.substring')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/sup/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/sup/index.html new file mode 100644 index 0000000000..118bbd1f2e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/sup/index.html @@ -0,0 +1,118 @@ +--- +title: String.prototype.sup() +slug: Web/JavaScript/Reference/Global_Objects/String/sup +tags: + - String.prototype.sup() +translation_of: Web/JavaScript/Reference/Global_Objects/String/sup +--- +
{{JSRef}} {{deprecated_header}}
+ +

sup()方法创建 一个{{HTMLElement("sup")}}HTML 元素,使字符串显示为上标。

+ +

语法

+ +
str.sup()
+ +

返回值

+ +

包含{{HTMLElement("sup")}} HTML 元素的字符串。

+ +

描述

+ +

sup() 方法将字符串嵌入 <sup> 标签中:"<sup>str</sup>".

+ +

示例

+ +

使用sub()sup()方法

+ +

下面的示例使用了{{jsxref("String.prototype.sub()", "sub()")}}和sup()方法来格式化字符串:

+ +
var superText = 'superscript';
+var subText = 'subscript';
+
+console.log('This is what a ' + superText.sup() + ' looks like.');
+// "这就是<sup>superscript</sup>的样子。"
+
+console.log('This is what a ' + subText.sub() + ' looks like.');
+// "这就是<sub>subscript</sub>的样子。"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-string.prototype.sup', 'String.prototype.sup')}}{{Spec2('ES6')}}初始定义。在 JavaScript 1.0 中实现。在(规范性)附件 B 中定义为用于 Web 浏览器的 ECMAScript 附加特性。
{{SpecName('ESDraft', '#sec-string.prototype.sup', 'String.prototype.sup')}}{{Spec2('ESDraft')}}在(规范性)附件 B 中定义为用于 Web 浏览器的 ECMAScript 附加特性。
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/tolocalelowercase/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/tolocalelowercase/index.html new file mode 100644 index 0000000000..a9709187a7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/tolocalelowercase/index.html @@ -0,0 +1,145 @@ +--- +title: String.prototype.toLocaleLowerCase() +slug: Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase +translation_of: Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase +--- +
{{JSRef}}
+ +

toLocaleLowerCase()方法根据任何指定区域语言环境设置的大小写映射,返回调用字符串被转换为小写的格式。

+ +

语法

+ +
str.toLocaleLowerCase()
+str.toLocaleLowerCase(locale)
+str.toLocaleLowerCase([locale, locale, ...])
+ +

参数

+ +
+
locale {{optional_inline}}
+
参数 locale 指明要转换成小写格式的特定语言区域。 如果以一个数组 {{jsxref("Array")}}形式给出多个locales,  最合适的地区将被选出来应用(参见best available locale)。默认的locale是主机环境的当前区域(locale)设置。
+
+ +

返回值

+ +

根据任何特定于语言环境的案例映射规则将被调用字串转换成小写格式的一个新字符串。

+ +

Exceptions

+ + + +

描述

+ +

toLocaleLowerCase() 方法返回根据任意区域语言大小写映射集而转换成小写格式的字符串。toLocaleLowerCase() 并不会影响字符串原本的值。在大多数情况下,该方法和调用 {{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}}的结果相同,但是在某些区域环境中,比如土耳其语,它的大小写映射并不遵循在Unicode中的默认的大小写映射,因此会有一个不同的结果。

+ +

例子

+ +

使用toLocaleLowerCase()

+ +
'ALPHABET'.toLocaleLowerCase(); // 'alphabet'
+
+'\u0130'.toLocaleLowerCase('tr') === 'i';    // true
+'\u0130'.toLocaleLowerCase('en-US') === 'i'; // false
+
+let locales = ['tr', 'TR', 'tr-TR', 'tr-u-co-search', 'tr-x-turkish'];
+'\u0130'.toLocaleLowerCase(locales) === 'i'; // true
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2.
{{SpecName('ES5.1', '#sec-15.5.4.17', 'String.prototype.toLocaleLowerCase')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.tolocalelowercase', 'String.prototype.toLocaleLowerCase')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype.tolocalelowercase', 'String.prototype.toLocaleLowerCase')}}{{Spec2('ESDraft')}}
{{SpecName('ES Int Draft', '#sup-string.prototype.tolocalelowercase', 'String.prototype.toLocaleLowerCase')}}{{Spec2('ES Int Draft')}}ES Intl 2017 added the localeparameter.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/tolocaleuppercase/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/tolocaleuppercase/index.html new file mode 100644 index 0000000000..9043db95c5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/tolocaleuppercase/index.html @@ -0,0 +1,91 @@ +--- +title: String.prototype.toLocaleUpperCase() +slug: Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase +translation_of: Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase +--- +
{{JSRef}}
+ +

toLocaleUpperCase() 方法根据本地主机语言环境把字符串转换为大写格式,并返回转换后的字符串。

+ +
{{EmbedInteractiveExample("pages/js/string-tolocaleuppercase.html")}}
+ + + +

语法

+ +
str.toLocaleUpperCase()
+str.toLocaleUpperCase(locale)
+str.toLocaleUpperCase([locale, locale, ...])
+
+ +

参数

+ +
+
locale {{optional_inline}}
+
The locale parameter indicates the locale to be used to convert to upper case according to any locale-specific case mappings. If multiple locales are given in an {{jsxref("Array")}}, the best available locale is used. The default locale is the host environment’s current locale.
+
+ +

返回值

+ +

A new string representing the calling string converted to upper case, according to any locale-specific case mappings.

+ +

Exceptions

+ + + +

描述

+ +

The toLocaleUpperCase() method returns the value of the string converted to upper case according to any locale-specific case mappings. toLocaleUpperCase() does not affect the value of the string itself. In most cases, this will produce the same result as {{jsxref("String.prototype.toUpperCase()", "toUpperCase()")}}, but for some locales, such as Turkish, whose case mappings do not follow the default case mappings in Unicode, there may be a different result.

+ +

Also notice that conversion is not necessarily a 1:1 character mapping, as some characters might result in two (or even more) characters when transformed to upper-case. Therefore the length of the result string can differ from the input length. This also implies that the conversion is not stable, so i.E. the following can return false:
+ x.toLocaleLowerCase() === x.toLocaleUpperCase().toLocaleLowerCase()

+ +

例子

+ +

使用 toLocaleUpperCase()

+ +
'alphabet'.toLocaleUpperCase(); // 'ALPHABET'
+
+'Gesäß'.toLocaleUpperCase(); // 'GESÄSS'
+
+'i\u0307'.toLocaleUpperCase('lt-LT'); // 'I'
+
+let locales = ['lt', 'LT', 'lt-LT', 'lt-u-co-phonebk', 'lt-x-lietuva'];
+'i\u0307'.toLocaleUpperCase(locales); // 'I'
+ +

规范

+ + + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-string.prototype.tolocaleuppercase', 'String.prototype.toLocaleUpperCase')}}
{{SpecName('ES Int Draft', '#sup-string.prototype.tolocaleuppercase', 'String.prototype.toLocaleUpperCase')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.toLocaleUpperCase")}}

+ +

相关链接

+ + + +
+
+
diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/tolowercase/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/tolowercase/index.html new file mode 100644 index 0000000000..e08a47bb55 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/tolowercase/index.html @@ -0,0 +1,136 @@ +--- +title: String.prototype.toLowerCase() +slug: Web/JavaScript/Reference/Global_Objects/String/toLowerCase +tags: + - JavaScript + - Method + - Prototype + - String + - toLowerCase() +translation_of: Web/JavaScript/Reference/Global_Objects/String/toLowerCase +--- +
{{JSRef}}
+ +

toLowerCase() 会将调用该方法的字符串值转为小写形式,并返回。

+ +

语法

+ +
str.toLowerCase()
+
+ +

+ +

返回值

+ +

一个新的字符串,表示转换为小写的调用字符串。

+ +

描述

+ +

toLowerCase 会将调用该方法的字符串值转为小写形式,并返回。toLowerCase 不会影响字符串本身的值。

+ +

示例

+ +

例子:使用 toLowerCase()

+ +
console.log('中文简体 zh-CN || zh-Hans'.toLowerCase());
+// 中文简体 zh-cn || zh-hans
+
+​console.log( "ALPHABET".toLowerCase() );
+// "alphabet"
+ +
+ +

说明

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.5.4.16', 'String.prototype.toLowerCase')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.tolowercase', 'String.prototype.toLowerCase')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype.tolowercase', 'String.prototype.toLowerCase')}}{{Spec2('ESDraft')}} 
+  
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/tosource/index.html new file mode 100644 index 0000000000..7914776a25 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/tosource/index.html @@ -0,0 +1,91 @@ +--- +title: String.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/String/toSource +translation_of: Web/JavaScript/Reference/Global_Objects/String/toSource +--- +
{{JSRef}} {{non-standard_header}}
+ +

toSource() 方法返回一个代表对象的源代码。

+ +

语法

+ +
String.toSource()
+str.toSource()
+
+ +

描述

+ +

toSource() 方法返回以下值:

+ +

对于内建对象 {{jsxref("String")}} , toSource()返回以下值说明源码不可用:

+ +
function String() {
+    [native code]
+}
+
+ +

对于实例{{jsxref("String")}} 或者字符串, toSource() 返回一个字符串表示源码.

+ +

这种方法通常在内部被JavaScript调用,而不是明确的代码。.

+ +

规范

+ +

不属于任何标准. 在 JavaScript 1.3实现了.

+ +

浏览器适配

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/tostring/index.html new file mode 100644 index 0000000000..192ae75b12 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/tostring/index.html @@ -0,0 +1,124 @@ +--- +title: String.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/String/toString +translation_of: Web/JavaScript/Reference/Global_Objects/String/toString +--- +
{{JSRef("Global_Objects", "String")}}
+ +

概述

+ +

toString() 方法返回指定对象的字符串形式。

+ +

语法

+ +
str.toString()
+
+ +

返回值

+ +

一个表示调用对象的字符串。

+ +

描述

+ +

String 对象覆盖了{{jsxref("Global_Objects/Object", "Object")}} 对象的 toString 方法;并没有继承 {{jsxref("Object.toString()")}}。对于 String 对象,toString 方法返回该对象的字符串形式,和 {{jsxref("String.prototype.valueOf()")}} 方法返回值一样。

+ +

示例

+ +

例子:使用 toString

+ +

下例输出一个字符串对象(String object)的字符串值:

+ +
var x = new String("Hello world");
+
+alert(x.toString())      // 输出 "Hello world"
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.5.4.2', 'String.prototype.toString')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype.tostring', 'String.prototype.toString')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype.tostring', 'String.prototype.toString')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/touppercase/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/touppercase/index.html new file mode 100644 index 0000000000..7d0edf43c5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/touppercase/index.html @@ -0,0 +1,87 @@ +--- +title: String.prototype.toUpperCase() +slug: Web/JavaScript/Reference/Global_Objects/String/toUpperCase +tags: + - JavaScript + - 原型 + - 字符串 + - 引用 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/toUpperCase +--- +
{{JSRef}}
+ +

toUpperCase() 方法将调用该方法的字符串转为大写形式并返回(如果调用该方法的值不是字符串类型会被强制转换)。

+ +
{{EmbedInteractiveExample("pages/js/string-touppercase.html","shorter")}}
+ + + +

语法

+ +
str.toUpperCase()
+ +

返回值

+ +

一个新的字符串,表示转换为大写的调用字符串。

+ +

错误处理

+ +
+
{{jsxref("TypeError(类型错误)")}}
+
在 {{jsxref("null")}} 或 {{jsxref("undefined")}}类型上调用,例如:String.prototype.toUpperCase.call(undefined).
+
+ +

描述

+ +

toUpperCase() 返回转为大写形式的字符串。此方法不会影响原字符串本身的值,因为JavaScript中字符串的值是不可改变的。

+ +

示例

+ +

基本用法

+ +
console.log('alphabet'.toUpperCase()); // 'ALPHABET'
+
+ +

将非字符串类型的 this (上下文)转为字符串

+ +

此方法会将任何非字符串类型的值转为字符串, 当你将其上下文 this 值设置为非字符串类型

+ +
const a = String.prototype.toUpperCase.call({
+  toString: function toString() {
+    return 'abcdef';
+  }
+});
+
+const b = String.prototype.toUpperCase.call(true);
+
+// 输出 'ABCDEF TRUE'。
+console.log(a, b);
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-string.prototype.touppercase', 'String.prototype.toUpperCase')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.toUpperCase")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/trim/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/trim/index.html new file mode 100644 index 0000000000..66e0d5171f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/trim/index.html @@ -0,0 +1,103 @@ +--- +title: String.prototype.trim() +slug: Web/JavaScript/Reference/Global_Objects/String/Trim +tags: + - ECMAScript 5 + - JavaScript + - Method + - Prototype + - String + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/Trim +--- +
+
+
{{JSRef}}
+
+
+ +

trim() 方法会从一个字符串的两端删除空白字符。在这个上下文中的空白字符是所有的空白字符 (space, tab, no-break space 等) 以及所有行终止符字符(如 LF,CR等)。

+ +

{{EmbedInteractiveExample("pages/js/string-trim.html")}}

+ + + +

语法

+ +
str.trim()
+ +

返回值

+ +

一个代表调用字符串两端去掉空白的新字符串。

+ +

描述

+ +

trim() 方法返回一个从两头去掉空白字符的字符串,并不影响原字符串本身。

+ +

例子

+ +

使用 trim()

+ +

下面的例子中将显示小写的字符串 'foo':

+ +
var orig = '   foo  ';
+console.log(orig.trim()); // 'foo'
+
+// 另一个 .trim() 例子,只从一边删除
+
+var orig = 'foo    ';
+console.log(orig.trim()); // 'foo'
+
+ +

兼容旧环境

+ +

如果 trim() 不存在,可以在所有代码前执行下面代码

+ +
if (!String.prototype.trim) {
+  String.prototype.trim = function () {
+    return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
+  };
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES5.1', '#sec-15.5.4.20', 'String.prototype.trim')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.8.1.
{{SpecName('ES6', '#sec-string.prototype.trim', 'String.prototype.trim')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype.trim', 'String.prototype.trim')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.trim")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/trimleft/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/trimleft/index.html new file mode 100644 index 0000000000..bc6133cecb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/trimleft/index.html @@ -0,0 +1,122 @@ +--- +title: String.prototype.trimStart() +slug: Web/JavaScript/Reference/Global_Objects/String/TrimLeft +tags: + - JavaScript + - Method + - Prototype + - String + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/trimStart +--- +
{{JSRef}}
+ +
trimStart() 方法从字符串的开头删除空格。trimLeft() 是此方法的别名。
+ +
{{EmbedInteractiveExample("pages/js/string-trimstart.html")}}
+ + + +

语法

+ +
str.trimStart();
+str.trimLeft();
+ +

返回值

+ +

一个新字符串,表示从其开头(左端)除去空格的调用字符串。

+ +

描述

+ +

trimStart() / trimLeft() 方法移除原字符串左端的连续空白符并返回一个新字符串,并不会直接修改原字符串本身。

+ +

别名

+ +

为了与 {{jsxref("String.prototype.padStart")}} 等函数保持一致,标准方法名称为trimStart。 但是,出于 Web 兼容性原因,trimLeft 仍然是 trimStart 的别名。在某些引擎中,这意味着:

+ +
String.prototype.trimLeft.name === "trimStart";
+ +

示例

+ +

使用 trimStart()

+ +

下面的例子输出了小写的字符串 "foo  "

+ +
var str = "   foo  ";
+
+console.log(str.length); // 8
+
+str = str.trimStart()    // 等同于 str = str.trimLeft();
+console.log(str.length); // 5
+console.log(str);        // "foo  "
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
String.prototype.{trimStart,trimEnd}proposalStage 4Expected to be part of ES2019
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.trimStart")}}

+ +

Polyfill

+ +
// https://github.com/FabioVergani/js-Polyfill_String-trimStart
+
+(function(w){
+    var String=w.String, Proto=String.prototype;
+
+    (function(o,p){
+        if(p in o?o[p]?false:true:true){
+            var r=/^\s+/;
+            o[p]=o.trimLeft||function(){
+                return this.replace(r,'')
+            }
+        }
+    })(Proto,'trimStart');
+
+})(window);
+
+
+/*
+ES6:
+(w=>{
+    const String=w.String, Proto=String.prototype;
+
+    ((o,p)=>{
+        if(p in o?o[p]?false:true:true){
+            const r=/^\s+/;
+            o[p]=o.trimLeft||function(){
+                return this.replace(r,'')
+            }
+        }
+    })(Proto,'trimStart');
+
+})(window);
+*/
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/trimright/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/trimright/index.html new file mode 100644 index 0000000000..9c8319cb29 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/trimright/index.html @@ -0,0 +1,84 @@ +--- +title: String.prototype.trimRight() +slug: Web/JavaScript/Reference/Global_Objects/String/TrimRight +tags: + - JavaScript + - Method + - Prototype + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/trimEnd +--- +
{{JSRef}}
+ +

trimEnd() 方法从一个字符串的末端移除空白字符。trimRight() 是这个方法的别名。

+ +

{{EmbedInteractiveExample("pages/js/string-trimend.html")}}

+ +

The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

+ +

语法

+ +
str.trimEnd();
+str.trimRight();
+ +

返回值

+ +

一个新字符串,表示从调用字串的末(右)端除去空白。

+ +

描述

+ +

trimEnd() / trimRight()方法移除原字符串右端的连续空白符并返回,trimEnd() / trimRight()方法并不会直接修改原字符串本身。

+ +

别名

+ +

为了与 {{jsxref("String.prototype.padEnd")}} 等函数保持一致,标准方法名称为trimEnd。 但是,出于Web兼容性原因,trimRight仍然是trimEnd的别名。 在某些引擎中,这意味着:

+ +
String.prototype.trimRight.name === "trimEnd";
+
+ +

示例

+ +

使用trimEnd()

+ +

下面的例子输出了小写的字符串"   foo":

+ +
var str = "   foo  ";
+
+alert(str.length); // 8
+
+str = str.trimRight();  // 或写成str = str.trimEnd();
+console.log(str.length); // 6
+console.log(str);       // '   foo'
+
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
String.prototype.{trimStart,trimEnd}proposalStage 4Expected to be part of ES2019
+ +

Browser compatibility

+ +

The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

+ +

{{Compat("javascript.builtins.String.trimEnd")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/valueof/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/valueof/index.html new file mode 100644 index 0000000000..7697c1074d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/valueof/index.html @@ -0,0 +1,58 @@ +--- +title: String.prototype.valueOf() +slug: Web/JavaScript/Reference/Global_Objects/String/valueOf +translation_of: Web/JavaScript/Reference/Global_Objects/String/valueOf +--- +
{{JSRef}}
+ +

valueOf() 方法返回  {{jsxref("String")}}  对象的原始值

+ +
{{EmbedInteractiveExample("pages/js/string-valueof.html")}}
+ +

语法

+ +
str.valueOf()
+ +

返回结果

+ +

A string representing the primitive value of a given {{jsxref("String")}} object.

+ +

描述

+ +

The valueOf() method of {{jsxref("String")}} returns the primitive value of a {{jsxref("String")}} object as a string data type. This value is equivalent to {{jsxref("String.prototype.toString()")}}.

+ +

此方法通常由JavaScript在内部调用,而不是在代码中显式调用。

+ +

示例

+ +

使用 valueOf()

+ +
var x = new String('Hello world');
+console.log(x.valueOf()); // Displays 'Hello world'
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-string.prototype.valueof', 'String.prototype.valueOf')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.valueOf")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/@@toprimitive/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/@@toprimitive/index.html new file mode 100644 index 0000000000..3a4624f560 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/@@toprimitive/index.html @@ -0,0 +1,55 @@ +--- +title: 'Symbol.prototype[@@toPrimitive]' +slug: Web/JavaScript/Reference/Global_Objects/Symbol/@@toPrimitive +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/@@toPrimitive +--- +
{{JSRef}}
+ +

[@@toPrimitive]() 方法可将 Symbol 对象转换为原始值。

+ +

语法

+ +
Symbol()[Symbol.toPrimitive](hint);
+
+ +

返回值

+ +

该原始值为指定的 {{jsxref("Symbol")}} 对象

+ +

描述

+ +

 {{jsxref("Symbol")}} 的 [@@toPrimitive]() 方法返回该 Symbol 对象原始值作为 Symbol 数据形式。 hint 参数未被使用。

+ +

JavaScript 调用 [@@toPrimitive]() 方法将一个对象转换为原始值表示。你不需要自己调用 [@@toPrimitive]() 方法;当对象需要被转换为原始值时,JavaScript 会自动地调用该方法。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-symbol.prototype-@@toprimitive', 'Symbol.prototype.@@toPrimitive')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.prototype-@@toprimitive', 'Symbol.prototype.@@toPrimitive')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Symbol.@@toPrimitive")}}

+ +

参考资料

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/asynciterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/asynciterator/index.html new file mode 100644 index 0000000000..f0c05da9ab --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/asynciterator/index.html @@ -0,0 +1,76 @@ +--- +title: Symbol.asyncIterator +slug: Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator +--- +
{{JSRef}}
+ +

Symbol.asyncIterator 符号指定了一个对象的默认异步迭代器。如果一个对象设置了这个属性,它就是异步可迭代对象,可用于for await...of循环。

+ + + +

描述

+ +

Symbol.asyncIterator 是一个用于访问对象的@@asyncIterator方法的内建符号。一个异步可迭代对象必须要有Symbol.asyncIterator属性。

+ +

{{js_property_attributes(0,0,0)}}

+ +

示例

+ +

自定义异步可迭代对象

+ +

你可以通过设置[Symbol.asyncIterator]属性来自定义异步可迭代对象。

+ +
const myAsyncIterable = new Object();
+myAsyncIterable[Symbol.asyncIterator] = async function*() {
+    yield "hello";
+    yield "async";
+    yield "iteration!";
+};
+
+(async () => {
+    for await (const x of myAsyncIterable) {
+        console.log(x);
+        // expected output:
+        //    "hello"
+        //    "async"
+        //    "iteration!"
+    }
+})();
+
+ +

内建异步可迭代对象

+ +

目前没有默认设定了[Symbol.asyncIterator]属性的JavaScript内建的对象。不过,WHATWG(网页超文本应用技术工作小组)Streams会被设定为第一批异步可迭代对象,[Symbol.asyncIterator] 最近已在设计规范中落地。

+ +

规范

+ + + + + + + + + + + + + + + + +
标准状态注释
{{SpecName('ES2018', '#sec-symbol.asynciterator', 'Symbol.asyncIterator')}}{{Spec2('ES2018')}}
+ +

浏览器兼容性

+ + + +

{{compat("javascript.builtins.Symbol.asyncIterator")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/description/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/description/index.html new file mode 100644 index 0000000000..1e52358a63 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/description/index.html @@ -0,0 +1,73 @@ +--- +title: Symbol.prototype.description +slug: Web/JavaScript/Reference/Global_Objects/Symbol/description +tags: + - JavaScript + - Property + - Prototype + - Symbol +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/description +--- +
{{JSRef}}
+ +

description 是一个只读属性,它会返回 {{jsxref("Symbol")}} 对象的可选描述的字符串。

+ +
{{EmbedInteractiveExample("pages/js/symbol-prototype-description.html")}}
+ + + +

语法

+ +
Symbol('myDescription').description;
+Symbol.iterator.description;
+Symbol.for('foo').description;
+
+ +

描述

+ +

{{jsxref("Symbol")}} 对象可以通过一个可选的描述创建,可用于调试,但不能用于访问 symbol 本身。Symbol.prototype.description 属性可以用于读取该描述。与 Symbol.prototype.toString() 不同的是它不会包含 "Symbol()" 的字符串。具体请看实例。

+ +

实例

+ +
Symbol('desc').toString();   // "Symbol(desc)"
+Symbol('desc').description;  // "desc"
+Symbol('').description;      // ""
+Symbol().description;        // undefined
+
+// well-known symbols
+Symbol.iterator.toString();  // "Symbol(Symbol.iterator)"
+Symbol.iterator.description; // "Symbol.iterator"
+
+// global symbols
+Symbol.for('foo').toString();  // "Symbol(foo)"
+Symbol.for('foo').description; // "foo"
+
+
+ +

规范

+ + + + + + + + + + + + +
SpecificationStatus
get Symbol.prototype.description proposalStage 3
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Symbol.description")}}

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/for/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/for/index.html new file mode 100644 index 0000000000..ee0b84406a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/for/index.html @@ -0,0 +1,154 @@ +--- +title: Symbol.for() +slug: Web/JavaScript/Reference/Global_Objects/Symbol/for +tags: + - JavaScript + - Method + - Symbol +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/for +--- +
{{JSRef}} 
+ +

Symbol.for(key) 方法会根据给定的键 key,来从运行时的 symbol 注册表中找到对应的 symbol,如果找到了,则返回它,否则,新建一个与该键关联的 symbol,并放入全局 symbol 注册表中。

+ +

语法

+ +
Symbol.for(key);
+ +

参数

+ +
+
key
+
一个字符串,作为 symbol 注册表中与某 symbol 关联的键(同时也会作为该 symbol 的描述)。
+
+ +

返回值

+ +

返回由给定的 key 找到的 symbol,否则就是返回新创建的 symbol。

+ +

描述

+ +

Symbol() 不同的是,用 Symbol.for() 方法创建的的 symbol 会被放入一个全局 symbol 注册表中。Symbol.for() 并不是每次都会创建一个新的 symbol,它会首先检查给定的 key 是否已经在注册表中了。假如是,则会直接返回上次存储的那个。否则,它会再新建一个。

+ +

全局 symbol 注册表

+ +

symbol 注册表中的记录结构:

+ + + + + + + + + + + + + + + + + +
全局 symbol 注册表中的一个记录
字段名字段值
[[key]]一个字符串,用来标识每个 symbol
[[symbol]]存储的 symbol 值
+ +

示例

+ +
Symbol.for("foo"); // 创建一个 symbol 并放入 symbol 注册表中,键为 "foo"
+Symbol.for("foo"); // 从 symbol 注册表中读取键为"foo"的 symbol
+
+
+Symbol.for("bar") === Symbol.for("bar"); // true,证明了上面说的
+Symbol("bar") === Symbol("bar"); // false,Symbol() 函数每次都会返回新的一个 symbol
+
+
+var sym = Symbol.for("mario");
+sym.toString();
+// "Symbol(mario)",mario 既是该 symbol 在 symbol 注册表中的键名,又是该 symbol 自身的描述字符串
+
+ +

为了防止冲突,最好给你要放入 symbol 注册表中的 symbol 带上键前缀。

+ +
Symbol.for("mdn.foo");
+Symbol.for("mdn.bar");
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-symbol.for', 'Symbol.for')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.for', 'Symbol.for')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatChrome(40) }}{{ CompatGeckoDesktop("36.0") }}{{ CompatNo() }}{{ CompatNo() }}10
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatGeckoMobile("36.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/hasinstance/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/hasinstance/index.html new file mode 100644 index 0000000000..ad28084f8e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/hasinstance/index.html @@ -0,0 +1,59 @@ +--- +title: Symbol.hasInstance +slug: Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance +--- +

{{JSRef}}

+ +

Symbol.hasInstance用于判断某对象是否为某构造器的实例。因此你可以用它自定义 {{jsxref("Operators/instanceof", "instanceof")}} 操作符在某个类上的行为。

+ +
+
{{EmbedInteractiveExample("pages/js/symbol-hasinstance.html")}}
+ + +
+ +
{{js_property_attributes(0,0,0)}}
+ +

示例

+ +

你可实现一个自定义的instanceof 行为,例如:

+ +
class MyArray {
+  static [Symbol.hasInstance](instance) {
+    return Array.isArray(instance);
+  }
+}
+console.log([] instanceof MyArray); // true
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
文档状态备注
{{SpecName('ES6', '#sec-symbol.hasinstance', 'Symbol.hasInstance')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.hasinstance', 'Symbol.hasInstance')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Symbol.hasInstance")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/index.html new file mode 100644 index 0000000000..9aec2c8777 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/index.html @@ -0,0 +1,227 @@ +--- +title: Symbol +slug: Web/JavaScript/Reference/Global_Objects/Symbol +tags: + - ECMAScript6 + - JavaScript + - Symbol +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol +--- +
{{JSRef}} 
+ +

symbol 是一种基本数据类型 ({{Glossary("Primitive", "primitive data type")}})。Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的symbol注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()"。

+ +

每个从Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的。更进一步的解析见—— glossary entry for Symbol

+ +
{{EmbedInteractiveExample("pages/js/symbol-constructor.html")}}
+ + + +

语法

+ +
Symbol([description])
+ +

参数

+ +
+
description {{optional_inline}}
+
可选的,字符串类型。对symbol的描述,可用于调试但不是访问symbol本身。
+
+ +

描述

+ +

直接使用Symbol()创建新的symbol类型,并用一个可选的字符串作为其描述。

+ +
var sym1 = Symbol();
+var sym2 = Symbol('foo');
+var sym3 = Symbol('foo');
+
+ +

上面的代码创建了三个新的symbol类型。 注意,Symbol("foo") 不会强制将字符串 “foo” 转换成symbol类型。它每次都会创建一个新的 symbol类型:

+ +
Symbol("foo") === Symbol("foo"); // false
+ +

下面带有 {{jsxref("Operators/new", "new")}} 运算符的语法将抛出 {{jsxref("TypeError")}} 错误:

+ +
var sym = new Symbol(); // TypeError
+ +

这会阻止创建一个显式的 Symbol 包装器对象而不是一个 Symbol 值。围绕原始数据类型创建一个显式包装器对象从 ECMAScript 6 开始不再被支持。 然而,现有的原始包装器对象,如 new Booleannew String以及new Number,因为遗留原因仍可被创建。

+ +

如果你真的想创建一个 Symbol 包装器对象 (Symbol wrapper object),你可以使用 Object() 函数:

+ +
var sym = Symbol("foo");
+typeof sym;     // "symbol"
+var symObj = Object(sym);
+typeof symObj;  // "object"
+ +

全局共享的 Symbol

+ +

上面使用Symbol() 函数的语法,不会在你的整个代码库中创建一个可用的全局的symbol类型。 要创建跨文件可用的symbol,甚至跨域(每个都有它自己的全局作用域) , 使用 {{jsxref("Symbol.for()")}} 方法和  {{jsxref("Symbol.keyFor()")}} 方法从全局的symbol注册表设置和取得symbol。

+ +

在对象中查找 Symbol 属性

+ +

{{jsxref("Object.getOwnPropertySymbols()")}} 方法让你在查找一个给定对象的符号属性时返回一个symbol类型的数组。注意,每个初始化的对象都是没有自己的symbol属性的,因此这个数组可能为空,除非你已经在对象上设置了symbol属性。

+ +

属性

+ +
+
Symbol.length
+
长度属性,值为0。
+
{{jsxref("Symbol.prototype")}}
+
symbol构造函数的原型。
+
+ +

众所周知的 symbols

+ +

除了自己创建的symbol,JavaScript还内建了一些在ECMAScript 5 之前没有暴露给开发者的symbol,它们代表了内部语言行为。它们可以使用以下属性访问:

+ +
+
+

迭代 symbols

+
+
{{jsxref("Symbol.iterator")}}
+
一个返回一个对象默认迭代器的方法。被 for...of 使用。
+
{{jsxref("Symbol.asyncIterator")}} {{experimental_inline}}
+
一个返回对象默认的异步迭代器的方法。被 for await of 使用。
+
+

正则表达式 symbols

+
+
{{jsxref("Symbol.match")}}
+
一个用于对字符串进行匹配的方法,也用于确定一个对象是否可以作为正则表达式使用。被 {{jsxref("String.prototype.match()")}} 使用。
+
{{jsxref("Symbol.replace")}}
+
一个替换匹配字符串的子串的方法. 被 {{jsxref("String.prototype.replace()")}} 使用。
+
{{jsxref("Symbol.search")}}
+
一个返回一个字符串中与正则表达式相匹配的索引的方法。被{{jsxref("String.prototype.search()")}} 使用。
+
{{jsxref("Symbol.split")}}
+
一个在匹配正则表达式的索引处拆分一个字符串的方法.。被 {{jsxref("String.prototype.split()")}} 使用。
+
+

其他 symbols

+
+
{{jsxref("Symbol.hasInstance")}}
+
一个确定一个构造器对象识别的对象是否为它的实例的方法。被 {{jsxref("Operators/instanceof", "instanceof")}} 使用。
+
{{jsxref("Symbol.isConcatSpreadable")}}
+
一个布尔值,表明一个对象是否应该flattened为它的数组元素。被 {{jsxref("Array.prototype.concat()")}} 使用。
+
{{jsxref("Symbol.unscopables")}}
+
拥有和继承属性名的一个对象的值被排除在与环境绑定的相关对象外。
+
{{jsxref("Symbol.species")}}
+
一个用于创建派生对象的构造器函数。
+
{{jsxref("Symbol.toPrimitive")}}
+
一个将对象转化为基本数据类型的方法。
+
{{jsxref("Symbol.toStringTag")}}
+
用于对象的默认描述的字符串值。被 {{jsxref("Object.prototype.toString()")}} 使用。
+
+ +

方法

+ +
+
{{jsxref("Symbol.for()", "Symbol.for(key)")}}
+
使用给定的key搜索现有的symbol,如果找到则返回该symbol。否则将使用给定的key在全局symbol注册表中创建一个新的symbol。
+
{{jsxref("Symbol.keyFor", "Symbol.keyFor(sym)")}}
+
从全局symbol注册表中,为给定的symbol检索一个共享的?symbol key。
+
+ +

Symbol 原型

+ +

所有 Symbols 继承自 {{jsxref("Symbol.prototype")}}.

+ +

属性

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/Symbol/prototype','Properties')}}

+ +

方法

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/Symbol/prototype','Methods')}}

+ +

示例

+ +

对 symbol 使用 typeof 运算符

+ +

 {{jsxref("Operators/typeof", "typeof")}}运算符能帮助你识别 symbol 类型

+ +
typeof Symbol() === 'symbol'
+typeof Symbol('foo') === 'symbol'
+typeof Symbol.iterator === 'symbol'
+
+ +

Symbol 类型转换

+ +

当使用 symbol 值进行类型转换时需要注意一些事情:

+ + + +

Symbols 与 for...in 迭代

+ +

Symbols 在 for...in 迭代中不可枚举。另外,{{jsxref("Object.getOwnPropertyNames()")}} 不会返回 symbol 对象的属性,但是你能使用 {{jsxref("Object.getOwnPropertySymbols()")}} 得到它们。

+ +
var obj = {};
+
+obj[Symbol("a")] = "a";
+obj[Symbol.for("b")] = "b";
+obj["c"] = "c";
+obj.d = "d";
+
+for (var i in obj) {
+   console.log(i); // logs "c" and "d"
+}
+ +

Symbols 与 JSON.stringify()

+ +

当使用 JSON.stringify() 时,以 symbol 值作为键的属性会被完全忽略:

+ +
JSON.stringify({[Symbol("foo")]: "foo"});
+// '{}'
+ +

更多细节,请看 {{jsxref("JSON.stringify()")}}。

+ +

Symbol 包装器对象作为属性的键

+ +

当一个 Symbol 包装器对象作为一个属性的键时,这个对象将被强制转换为它包装过的 symbol 值:

+ +
var sym = Symbol("foo");
+var obj = {[sym]: 1};
+obj[sym];            // 1
+obj[Object(sym)];    // still 1
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
标准状态注释
{{SpecName('ES6', '#sec-symbol-objects', 'Symbol')}}{{Spec2('ES6')}}原始定义
{{SpecName('ESDraft', '#sec-symbol-objects', 'Symbol')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Symbol")}}

+ +

参考文档

+ + + + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/isconcatspreadable/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/isconcatspreadable/index.html new file mode 100644 index 0000000000..ed98d2bb29 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/isconcatspreadable/index.html @@ -0,0 +1,97 @@ +--- +title: Symbol.isConcatSpreadable +slug: Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable +tags: + - JavaScript + - Symbol +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable +--- +
{{JSRef}}
+ +

内置的Symbol.isConcatSpreadable符号用于配置某对象作为{{jsxref("Array.prototype.concat()")}}方法的参数时是否展开其数组元素。

+ +
{{EmbedInteractiveExample("pages/js/symbol-isconcatspreadable.html")}}
+ +

描述

+ +

@@isConcatSpreadable 符号 (Symbol.isConcatSpreadable) 可以直接定义为对象属性或继承而来,它是布尔类型。它可以控制数组或类似数组(array-like)的对象的行为:

+ + + +

{{js_property_attributes(0,0,0)}}

+ +

示例

+ +

数组

+ +

默认情况下,{{jsxref("Array.prototype.concat()")}} 展开其元素连接到结果中:

+ +
var alpha = ['a', 'b', 'c'],
+    numeric = [1, 2, 3];
+
+var alphaNumeric = alpha.concat(numeric);
+
+console.log(alphaNumeric); // 结果: ['a', 'b', 'c', 1, 2, 3]
+
+ +

设置Symbol.isConcatSpreadablefalse

+ +
var alpha = ['a', 'b', 'c'],
+    numeric = [1, 2, 3];
+
+numeric[Symbol.isConcatSpreadable] = false;
+var alphaNumeric = alpha.concat(numeric);
+
+console.log(alphaNumeric); // 结果: ['a', 'b', 'c', [1, 2, 3] ]
+
+ +

Array-like 对象

+ +

对于类数组 (array-like)对象,默认不展开。期望展开其元素用于连接,需要设置 Symbol.isConcatSpreadable 为true:

+ +
var x = [1, 2, 3];
+
+var fakeArray = {
+  [Symbol.isConcatSpreadable]: true,
+  length: 2,
+  0: "hello",
+  1: "world"
+}
+
+x.concat(fakeArray); // [1, 2, 3, "hello", "world"]
+
+ +

技术标准

+ + + + + + + + + + + + + + + + + + + +
标准状态备注
{{SpecName('ES6', '#sec-symbol.isconcatspreadable', 'Symbol.isconcatspreadable')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.isconcatspreadable', 'Symbol.isconcatspreadable')}}{{Spec2('ESDraft')}}No change.
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Symbol.isConcatSpreadable")}}

+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/iterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/iterator/index.html new file mode 100644 index 0000000000..558a1323ca --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/iterator/index.html @@ -0,0 +1,94 @@ +--- +title: Symbol.iterator +slug: Web/JavaScript/Reference/Global_Objects/Symbol/iterator +tags: + - ECMAScript 2015 + - JavaScript + - Property + - Symbol +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/iterator +--- +
{{JSRef}}
+ +

Symbol.iterator 为每一个对象定义了默认的迭代器。该迭代器可以被 for...of 循环使用。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

当需要对一个对象进行迭代时(比如开始用于一个for..of循环中),它的@@iterator方法都会在不传参情况下被调用,返回的迭代器用于获取要迭代的值。

+ +

一些内置类型拥有默认的迭代器行为,其他类型(如 {{jsxref("Object")}})则没有。下表中的内置类型拥有默认的@@iterator方法:

+ + + +

更多信息请参见迭代协议

+ +

示例

+ +

自定义迭代器

+ +

我们可以像下面这样创建自定义的迭代器:

+ +
var myIterable = {}
+myIterable[Symbol.iterator] = function* () {
+    yield 1;
+    yield 2;
+    yield 3;
+};
+[...myIterable] // [1, 2, 3]
+
+ +

不符合标准的迭代器

+ +

如果一个迭代器 @@iterator 没有返回一个迭代器对象,那么它就是一个不符合标准的迭代器,这样的迭代器将会在运行期抛出异常,甚至非常诡异的 Bug。

+ +
var nonWellFormedIterable = {}
+nonWellFormedIterable[Symbol.iterator] = () => 1
+[...nonWellFormedIterable] // TypeError: [] is not a function
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-symbol.iterator', 'Symbol.iterator')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.iterator', 'Symbol.iterator')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Symbol.iterator")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/keyfor/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/keyfor/index.html new file mode 100644 index 0000000000..150ae66f02 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/keyfor/index.html @@ -0,0 +1,115 @@ +--- +title: Symbol.keyFor() +slug: Web/JavaScript/Reference/Global_Objects/Symbol/keyFor +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/keyFor +--- +
{{JSRef("Global_Objects", "Symbol")}}
+ +

概述

+ +

Symbol.keyFor(sym) 方法用来获取全局symbol 注册表中与某个 symbol 关联的键。

+ +

语法

+ +
Symbol.keyFor(sym);
+ +

参数

+ +
+
sym
+
必选参数,需要查找键值的某个 Symbol 。
+
+ +

返回值

+ +
+
如果全局注册表中查找到该symbol,则返回该symbol的key值,返回值为字符串类型。否则返回undefined
+
+ +

示例

+ +
// 创建一个全局 Symbol
+var globalSym = Symbol.for("foo");
+Symbol.keyFor(globalSym); // "foo"
+
+var localSym = Symbol();
+Symbol.keyFor(localSym); // undefined,
+
+// 以下Symbol不是保存在全局Symbol注册表中
+Symbol.keyFor(Symbol.iterator) // undefined
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-symbol.keyfor', 'Symbol.keyFor')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatNo() }}{{ CompatGeckoDesktop("33.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatGeckoMobile("33.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/match/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/match/index.html new file mode 100644 index 0000000000..793b0ea01c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/match/index.html @@ -0,0 +1,78 @@ +--- +title: Symbol.match +slug: Web/JavaScript/Reference/Global_Objects/Symbol/match +tags: + - JavaScript + - Symbol + - 属性 +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/match +--- +
{{JSRef}}
+ +

Symbol.match 指定了匹配的是正则表达式而不是字符串。{{jsxref("String.prototype.match()")}} 方法会调用此函数。

+ +
{{EmbedInteractiveExample("pages/js/symbol-match.html")}}
+ + + +

描述

+ +

此函数还用于标识对象是否具有正则表达式的行为。比如, {{jsxref("String.prototype.startsWith()")}},{{jsxref("String.prototype.endsWith()")}} 和 {{jsxref("String.prototype.includes()")}} 这些方法会检查其第一个参数是否是正则表达式,是正则表达式就抛出一个{{jsxref("TypeError")}}。现在,如果 match symbol 设置为 false(或者一个 {{Glossary("Falsy", "假值")}}),就表示该对象不打算用作正则表达式对象。

+ +

{{js_property_attributes(0,0,0)}}

+ +

示例

+ +

禁止表达式检查

+ +

下面代码会抛出一个 {{jsxref("TypeError")}}:

+ +
"/bar/".startsWith(/bar/);
+
+// Throws TypeError, 因为 /bar/ 是一个正则表达式
+// 且 Symbol.match 没有修改。
+ +

但是,如果你将 Symbol.match 置为 false,使用 match 属性的表达式检查会认为该象不是正则表达式对象。startsWithendsWith 方法将不会抛出 TypeError

+ +
var re = /foo/;
+re[Symbol.match] = false;
+"/foo/".startsWith(re); // true
+"/baz/".endsWith(re);   // false
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-symbol.match', 'Symbol.match')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.match', 'Symbol.match')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.Symbol.match")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/matchall/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/matchall/index.html new file mode 100644 index 0000000000..730107b31c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/matchall/index.html @@ -0,0 +1,65 @@ +--- +title: Symbol.matchAll +slug: Web/JavaScript/Reference/Global_Objects/Symbol/matchAll +tags: + - JavaScript + - Property + - Reference + - Symbol +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/matchAll +--- +
{{JSRef}}
+ +

Symbol.matchAll 返回一个迭代器,该迭代器根据字符串生成正则表达式的匹配项。此函数可以被 {{jsxref("String.prototype.matchAll()")}} 方法调用。

+ +
{{EmbedInteractiveExample("pages/js/symbol-matchall.html")}}
+ + + +

描述

+ +
+

此Symbol用于 {{jsxref("String.prototype.matchAll()")}} 特别是 {{jsxref("RegExp.@@matchAll", "RegExp.prototype[@@matchAll]()")}}。下面两个例子返回相同的结果:

+ +
'abc'.matchAll(/a/);
+
+/a/[Symbol.matchAll]('abc');
+ +

此方法用于自定义 {{jsxref("RegExp")}} 子类中的匹配行为。

+ +

{{js_property_attributes(0,0,0)}}

+
+ +

示例

+ +

更多示例请查阅 {{jsxref("String.prototype.matchAll()")}} 和 {{jsxref("RegExp.@@matchAll", "RegExp.prototype[@@matchAll]()")}}。

+ +

规范

+ + + + + + + + + + + + + + +
文档状态备注
{{SpecName('ESDraft', '#sec-symbol.matchall', 'Symbol.matchAll')}}{{Spec2('ESDraft')}} 
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.Symbol.matchAll")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/prototype/index.html new file mode 100644 index 0000000000..4ba14f92c5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/prototype/index.html @@ -0,0 +1,66 @@ +--- +title: Symbol.prototype +slug: Web/JavaScript/Reference/Global_Objects/Symbol/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol +--- +
{{JSRef}}
+ +

Symbol.prototype 表示 {{jsxref("Symbol")}} 构造函数的原型。.

+ +
{{EmbedInteractiveExample("pages/js/symbol-prototype.html")}}
+ +

Description

+ +

{{jsxref("Symbol")}} 继承自 {{jsxref("Symbol.prototype")}}. 你可以使用构造函数的原型对象来给所有Symbol实例添加属性或者方法。

+ +

{{js_property_attributes(0,0,0)}}

+ +

Properties

+ +
+
Symbol.prototype.constructor
+
返回创建实例原型的函数. 默认为 {{jsxref("Symbol")}} 函数。
+
{{jsxref("Symbol.prototype.description")}}
+
一个包含symbol描述的只读字符串。
+
+ +

Methods

+ +
+
{{jsxref("Symbol.prototype.toSource()")}} {{Non-standard_inline}}
+
返回包含{{jsxref("Global_Objects/Symbol", "Symbol")}} 对象源码的字符串。覆盖{{jsxref("Object.prototype.toSource()")}} 方法。
+
{{jsxref("Symbol.prototype.toString()")}}
+
返回包含Symbol描述符的字符串。 覆盖{{jsxref("Object.prototype.toString()")}} 方法。
+
{{jsxref("Symbol.prototype.valueOf()")}}
+
返回 {{jsxref("Symbol")}} 对象的初始值.。覆盖 {{jsxref("Object.prototype.valueOf()")}} 方法。
+
{{jsxref("Symbol.prototype.@@toPrimitive()", "Symbol.prototype[@@toPrimitive]")}}
+
 返回{{jsxref("Symbol")}}对象的初始值。
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-symbol.prototype', 'Symbol.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.prototype', 'Symbol.prototype')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ +

{{Compat("javascript.builtins.Symbol.prototype")}}

+ +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/replace/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/replace/index.html new file mode 100644 index 0000000000..b5a5eeb5ea --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/replace/index.html @@ -0,0 +1,52 @@ +--- +title: Symbol.replace +slug: Web/JavaScript/Reference/Global_Objects/Symbol/replace +tags: + - JavaScript + - Symbol +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/replace +--- +
{{JSRef}}
+ +

Symbol.replace 这个属性指定了当一个字符串替换所匹配字符串时所调用的方法。{{jsxref("String.prototype.replace()")}} 方法会调用此方法。

+ +

更多信息, 详见 {{jsxref("RegExp.@@replace", "RegExp.prototype[@@replace]()")}} 和 {{jsxref("String.prototype.replace()")}}。

+ +

{{EmbedInteractiveExample("pages/js/symbol-replace.html")}}

+ +
{{js_property_attributes(0,0,0)}}
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-symbol.replace', 'Symbol.replace')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.replace', 'Symbol.replace')}}{{Spec2('ESDraft')}}
+ +

Browser compatibility

+ +

{{Compat("javascript.builtins.Symbol.replace")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/search/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/search/index.html new file mode 100644 index 0000000000..c1efdd302e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/search/index.html @@ -0,0 +1,113 @@ +--- +title: Symbol.search +slug: Web/JavaScript/Reference/Global_Objects/Symbol/search +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/search +--- +
{{JSRef}}
+ +
+ +

Symbol.search 指定了一个搜索方法,这个方法接受用户输入的正则表达式,返回该正则表达式在字符串中匹配到的下标,这个方法由以下的方法来调用 {{jsxref("String.prototype.search()")}}。

+ +

更多信息请参见 {{jsxref("RegExp.@@search", "RegExp.prototype[@@search]()")}} 和{{jsxref("String.prototype.search()")}}.

+ +
{{js_property_attributes(0,0,0)}}
+ +

案例

+ +

自定义字符串搜索

+ +
class caseInsensitiveSearch {
+  constructor(value) {
+    this.value = value.toLowerCase();
+  }
+  [Symbol.search](string) {
+    return string.toLowerCase().indexOf(this.value);
+  }
+}
+
+console.log('foobar'.search(new caseInsensitiveSearch('BaR')));
+// expected output: 3
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-symbol.search', 'Symbol.search')}}{{Spec2('ES2015')}}规范中定义的几个部分
{{SpecName('ESDraft', '#sec-symbol.search', 'Symbol.search')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持{{CompatChrome(50)}}{{ CompatGeckoDesktop(49) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile(49) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/species/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/species/index.html new file mode 100644 index 0000000000..aeb9918a47 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/species/index.html @@ -0,0 +1,73 @@ +--- +title: Symbol.species +slug: Web/JavaScript/Reference/Global_Objects/Symbol/species +tags: + - ECMAScript 2015 + - JavaScript + - Property + - Symbol +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/species +--- +
{{JSRef}}
+ +

知名的 Symbol.species 是个函数值属性,其被构造函数用以创建派生对象。

+ +
{{EmbedInteractiveExample("pages/js/symbol-species.html")}}
+ + + +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

species 访问器属性允许子类覆盖对象的默认构造函数。

+ +

示例

+ +

你可能想在扩展数组类 MyArray 上返回 {{jsxref("Array")}} 对象。 例如,当使用例如 {{jsxref("Array.map", "map()")}} 这样的方法返回默认的构造函数时,你希望这些方法能够返回父级的 Array 对象,以取代 MyArray 对象。Symbol.species 允许你这么做:

+ +
class MyArray extends Array {
+  // 覆盖 species 到父级的 Array 构造函数上
+  static get [Symbol.species]() { return Array; }
+}
+var a = new MyArray(1,2,3);
+var mapped = a.map(x => x * x);
+
+console.log(mapped instanceof MyArray); // false
+console.log(mapped instanceof Array);   // true
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-symbol.species', 'Symbol.species')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.species', 'Symbol.species')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Symbol.species")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/split/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/split/index.html new file mode 100644 index 0000000000..53b98d57cd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/split/index.html @@ -0,0 +1,117 @@ +--- +title: Symbol.split +slug: Web/JavaScript/Reference/Global_Objects/Symbol/split +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/split +--- +
{{JSRef}}
+ +

Symbol.split 指向 一个正则表达式的索引处分割字符串的方法。 这个方法通过 {{jsxref("String.prototype.split()")}} 调用。

+ +

详情请参阅{{jsxref("RegExp.@@split", "RegExp.prototype[@@split]()")}} 和{{jsxref("String.prototype.split()")}}.

+ +
{{EmbedInteractiveExample("pages/js/symbol-split.html")}}
+ + + +
{{js_property_attributes(0,0,0)}}
+ +

示例

+ +

[Symbol.split]指向‘aba’.split(/a/)

+ +
/a/[Symbol.split]('aba',3)
+ +

"dayinlove".split(exp)调用[Symbol.split](str)处理,并把实参"dayinlove"传给形参str

+ +
var exp =  {
+        pat:'in',
+        [Symbol.split](str) {
+          return str.split(this.pat);
+          }
+    }
+
+    "dayinlove".split(exp);
+//["day", "love"]
+ +

技术标准

+ + + + + + + + + + + + + + + + + + + +
文档状态备注
{{SpecName('ES6', '#sec-symbol.split', 'Symbol.split')}}{{Spec2('ES6')}}初始定义.
{{SpecName('ESDraft', '#sec-symbol.split', 'Symbol.split')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(50)}}{{ CompatGeckoDesktop(49) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile(49) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/toprimitive/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/toprimitive/index.html new file mode 100644 index 0000000000..61e4d36fb9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/toprimitive/index.html @@ -0,0 +1,87 @@ +--- +title: Symbol.toPrimitive +slug: Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive +--- +
{{JSRef}}
+ +
+ +

Symbol.toPrimitive 是一个内置的 Symbol 值,它是作为对象的函数值属性存在的,当一个对象转换为对应的原始值时,会调用此函数。

+ +
{{EmbedInteractiveExample("pages/js/symbol-toprimitive.html")}}
+ +

描述

+ +

在 Symbol.toPrimitive 属性(用作函数值)的帮助下,一个对象可被转换为原始值。该函数被调用时,会被传递一个字符串参数 hint ,表示要转换到的原始值的预期类型。 hint 参数的取值是 "number""string" 和 "default" 中的任意一个。

+ +

{{js_property_attributes(0,0,0)}}

+ +

示例

+ +

下面的例子展示了, Symbol.toPrimitive 属性是如何干扰一个对象转换为原始值时输出的结果的。

+ +
// 一个没有提供 Symbol.toPrimitive 属性的对象,参与运算时的输出结果
+var obj1 = {};
+console.log(+obj1);     // NaN
+console.log(`${obj1}`); // "[object Object]"
+console.log(obj1 + ""); // "[object Object]"
+
+// 接下面声明一个对象,手动赋予了 Symbol.toPrimitive 属性,再来查看输出结果
+var obj2 = {
+  [Symbol.toPrimitive](hint) {
+    if (hint == "number") {
+      return 10;
+    }
+    if (hint == "string") {
+      return "hello";
+    }
+    return true;
+  }
+};
+console.log(+obj2);     // 10      -- hint 参数值是 "number"
+console.log(`${obj2}`); // "hello" -- hint 参数值是 "string"
+console.log(obj2 + ""); // "true"  -- hint 参数值是 "default"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ES6', '#sec-symbol.toprimitive', 'Symbol.toPrimitive')}}{{Spec2('ES6')}}原始定义
{{SpecName('ESDraft', '#sec-symbol.toprimitive', 'Symbol.toPrimitive')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

 {{Compat("javascript.builtins.Symbol.toPrimitive")}}

+ +
+ + + +
+
+ +

其他资料

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/tosource/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/tosource/index.html new file mode 100644 index 0000000000..56d7571d55 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/tosource/index.html @@ -0,0 +1,93 @@ +--- +title: Symbol.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/Symbol/toSource +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/toSource +--- +
{{JSRef}} {{Non-standard_header}}
+ +

toSource() 方法返回代表该对象源码的字符串。

+ +

该方法通常由JavaScript内部调用。

+ +

Syntax

+ +
Symbol.toSource()
+
+var sym = Symbol()
+sym.toSource()
+ +

Description

+ +

toSource方法返回以下值:

+ +

对于内建Symbol对象, toSource 返回以下字符串,表明源代码不可见:

+ +
"function Symbol() {
+   [native code]
+}"
+ +

对于Symbol实例, toSource 返回代表源码的字符串。

+ +
"Symbol()"
+ +

Specifications

+ +

还未成为任何标准的一部分

+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{ CompatGeckoDesktop("36.0") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile("36.0") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/tostring/index.html new file mode 100644 index 0000000000..1ed899232e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/tostring/index.html @@ -0,0 +1,116 @@ +--- +title: Symbol.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/Symbol/toString +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/toString +--- +
{{JSRef("Global_Objects", "Symbol")}}
+ +

概述

+ +

toString() 方法返回当前 symbol 对象的字符串表示。

+ +

语法

+ +
symbol.toString();
+ +

描述

+ +

{{jsxref("Symbol")}} 对象拥有自己的 toString 方法,因而遮蔽了原型链上的 {{jsxref("Object.prototype.toString()")}}。

+ +

symbol 原始值不能转换为字符串

+ +

symbol 原始值不能转换为字符串,所以只能先转换成它的包装对象,再调用 toString() 方法:

+ +
Symbol("foo") + "bar";
+// TypeError: Can't convert symbol to string
+Symbol("foo").toString() + "bar"
+// "Symbol(foo)bar",就相当于下面的:
+Object(Symbol("foo")).toString() + "bar"
+// "Symbol(foo)bar"
+
+ +

示例

+ +
Symbol("desc").toString();   // "Symbol(desc)"
+
+// well-known symbols
+Symbol.iterator.toString();  // "Symbol(Symbol.iterator)
+
+// global symbols
+Symbol.for("foo").toString() // "Symbol(foo)"
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-symbol.prototype.tostring', 'Symbol.prototype.toString')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatGeckoDesktop("33.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatGeckoMobile("33.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/tostringtag/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/tostringtag/index.html new file mode 100644 index 0000000000..c09f904a6e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/tostringtag/index.html @@ -0,0 +1,129 @@ +--- +title: Symbol.toStringTag +slug: Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag +--- +
{{JSRef}}
+ +

Symbol.toStringTag 是一个内置 symbol,它通常作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型标签,通常只有内置的 {{jsxref("Object.prototype.toString()")}} 方法会去读取这个标签并把它包含在自己的返回值里。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

许多内置的 JavaScript 对象类型即便没有 toStringTag 属性,也能被 toString() 方法识别并返回特定的类型标签,比如:

+ +
Object.prototype.toString.call('foo');     // "[object String]"
+Object.prototype.toString.call([1, 2]);    // "[object Array]"
+Object.prototype.toString.call(3);         // "[object Number]"
+Object.prototype.toString.call(true);      // "[object Boolean]"
+Object.prototype.toString.call(undefined); // "[object Undefined]"
+Object.prototype.toString.call(null);      // "[object Null]"
+// ... and more
+
+ +

另外一些对象类型则不然,toString() 方法能识别它们是因为引擎为它们设置好了 toStringTag 标签:

+ +
Object.prototype.toString.call(new Map());       // "[object Map]"
+Object.prototype.toString.call(function* () {}); // "[object GeneratorFunction]"
+Object.prototype.toString.call(Promise.resolve()); // "[object Promise]"
+// ... and more
+
+ +

但你自己创建的类不会有这份特殊待遇,toString() 找不到 toStringTag 属性时只好返回默认的 Object 标签:

+ +
class ValidatorClass {}
+
+Object.prototype.toString.call(new ValidatorClass()); // "[object Object]"
+
+ +

加上 toStringTag 属性,你的类也会有自定义的类型标签了:

+ +
class ValidatorClass {
+  get [Symbol.toStringTag]() {
+    return "Validator";
+  }
+}
+
+Object.prototype.toString.call(new ValidatorClass()); // "[object Validator]"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-symbol.tostringtag', 'Symbol.toStringTag')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.tostringtag', 'Symbol.toStringTag')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(49)}}{{CompatGeckoDesktop(51)}}{{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile(51)}}{{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/unscopables/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/unscopables/index.html new file mode 100644 index 0000000000..ab6483defd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/unscopables/index.html @@ -0,0 +1,89 @@ +--- +title: Symbol.unscopables +slug: Web/JavaScript/Reference/Global_Objects/Symbol/unscopables +tags: + - ECMAScript 2015 + - JavaScript + - Property + - Symbol +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/unscopables +--- +
{{JSRef}}
+ +

Symbol.unscopables 指用于指定对象值,其对象自身和继承的从关联对象的 with 环境绑定中排除的属性名称。

+ +
{{EmbedInteractiveExample("pages/js/symbol-unscopables.html")}}
+ +

描述

+ +

可以在任何对象上定义 @@unscopables symbol (Symbol.unscopables),用于排除属性名称并与 with 环境绑定在一起作为词法变量公开。 请注意,如果使用 Strict mode,语句将不可用,并且可能也不需要 symbol。

+ +

在 unscopables 对象上设置属性为 true,将使其 unscopable 并且因此该属性也将不会在词法环境变量中出现。 如果设置属性为 false ,则将使其可 scopable 并且该属性会出现在词法环境变量中。

+ +

{{js_property_attributes(0,0,0)}}

+ +

示例

+ +

下列的代码可兼容 ES5 及以下版本。然而,在 ECMAScript 2015 (ES6) 或其后续版本中,{{jsxref("Array.prototype.keys()")}} 方法才会出现。意味着内部 with 环境“关键字” 存在该方法,但变量中不会存在。 也就是说,当 unscopables symbol 被展示时,内置的unscopables 设置是由 {{jsxref("Array.@@unscopables", "Array.prototype[@@unscopables]")}} 展示并实现的, 一些 Array 的方法 将作为 scoped 放入 with 语句中。

+ +
var keys = [];
+
+with(Array.prototype) {
+  keys.push("something");
+}
+
+Object.keys(Array.prototype[Symbol.unscopables]);
+// ["copyWithin", "entries", "fill", "find", "findIndex",
+//  "includes", "keys", "values"]
+
+ +

你也可以为你自己的对象设置 unscopables 。

+ +
var obj = {
+  foo: 1,
+  bar: 2
+};
+
+obj[Symbol.unscopables] = {
+  foo: false,
+  bar: true
+};
+
+with(obj) {
+  console.log(foo); // 1
+  console.log(bar); // ReferenceError: bar is not defined
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-symbol.unscopables', 'Symbol.unscopables')}}{{Spec2('ES2015')}}首次定义
{{SpecName('ESDraft', '#sec-symbol.unscopables', 'Symbol.unscopables')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Symbol.unscopables")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/valueof/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/valueof/index.html new file mode 100644 index 0000000000..a5beee61d4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/symbol/valueof/index.html @@ -0,0 +1,106 @@ +--- +title: Symbol.prototype.valueOf() +slug: Web/JavaScript/Reference/Global_Objects/Symbol/valueOf +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol/valueOf +--- +
{{JSRef("Global_Objects", "Symbol")}}
+ +

概述

+ +

valueOf() 方法返回当前 symbol 对象所包含的 symbol 原始值。

+ +

语法

+ +
symbol.valueOf();
+
+ +

描述

+ +

在 JavaScript 中,虽然大多数类型的对象在某些操作下都会自动的隐式调用自身的 valueOf() 方法或者 toString() 方法来将自己转换成一个原始值,但 symbol 对象不会这么干,symbol 对象无法隐式转换成对应的原始值:

+ +
Object(Symbol("foo")) + "bar";
+// TypeError: can't convert symbol object to primitive
+// 无法隐式的调用 valueOf() 方法
+
+Object(Symbol("foo")).valueOf() + "bar";
+// TypeError:  can't convert symbol to string
+// 手动调用 valueOf() 方法,虽然转换成了原始值,但 symbol 原始值不能转换为字符串
+
+Object(Symbol("foo")).toString() + "bar";
+// "Symbol(foo)bar",需要手动调用 toString() 方法才行
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-symbol.prototype.valueof', 'Symbol.prototype.valueOf')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatGeckoDesktop("33.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatGeckoMobile("33.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/syntaxerror/index.html b/files/zh-cn/web/javascript/reference/global_objects/syntaxerror/index.html new file mode 100644 index 0000000000..fed587b744 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/syntaxerror/index.html @@ -0,0 +1,171 @@ +--- +title: SyntaxError +slug: Web/JavaScript/Reference/Global_Objects/SyntaxError +tags: + - Error + - JavaScript + - Object + - SyntaxError +translation_of: Web/JavaScript/Reference/Global_Objects/SyntaxError +--- +
{{JSRef}}
+ +

SyntaxError 对象代表尝试解析语法上不合法的代码的错误。

+ +

描述

+ +

当Javascript语言解析代码时,Javascript引擎发现了不符合语法规范的tokens或token顺序时抛出SyntaxError.

+ +

语法

+ +
new SyntaxError([message[, fileName[, lineNumber]]])
+ +

参数

+ +
+
message
+
可选的. 可阅读的错误描述信息
+
fileName {{non-standard_inline}}
+
可选的. 包含引发异常的代码的文件名
+
lineNumber {{non-standard_inline}}
+
可选的. 包含引发异常的代码的行号
+
+ +

属性

+ +
+
{{jsxref("SyntaxError.prototype")}}
+
允许SyntaxError对象添加属性.
+
+ +

方法

+ +

全局 SyntaxError 自身不包含任何方法, 但从原型链中继承了一些方法.

+ +

SyntaxError 实例

+ +

属性

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype', '属性')}}
+ +

方法

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype', '方法')}}
+ +

示例

+ +

捕获 SyntaxError

+ +
try {
+  eval('hoo bar');
+} catch (e) {
+  console.log(e instanceof SyntaxError); // true
+  console.log(e.message);                // "missing ; before statement"
+  console.log(e.name);                   // "SyntaxError"
+  console.log(e.fileName);               // "Scratchpad/1"
+  console.log(e.lineNumber);             // 1
+  console.log(e.columnNumber);           // 4
+  console.log(e.stack);                  // "@Scratchpad/1:2:3\n"
+}
+
+ +

创建 SyntaxError

+ +
try {
+  throw new SyntaxError('Hello', 'someFile.js', 10);
+} catch (e) {
+  console.log(e instanceof SyntaxError); // true
+  console.log(e.message);                // "Hello"
+  console.log(e.name);                   // "SyntaxError"
+  console.log(e.fileName);               // "someFile.js"
+  console.log(e.lineNumber);             // 10
+  console.log(e.columnNumber);           // 0
+  console.log(e.stack);                  // "@Scratchpad/2:11:9\n"
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.11.6.4', 'SyntaxError')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-native-error-types-used-in-this-standard-syntaxerror', 'SyntaxError')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/syntaxerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/syntaxerror/prototype/index.html new file mode 100644 index 0000000000..68a9ff3432 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/syntaxerror/prototype/index.html @@ -0,0 +1,132 @@ +--- +title: SyntaxError.prototype +slug: Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype +tags: + - Error + - JavaScript + - Property + - Prototype + - SyntaxError +translation_of: Web/JavaScript/Reference/Global_Objects/SyntaxError +--- +
{{JSRef}}
+ +

SyntaxError.prototype 属性表示{{jsxref("SyntaxError")}} 构造器的原型.

+ +

描述

+ +

所有 {{jsxref("SyntaxError")}} 实例继承自 SyntaxError.prototype. 你可以使用该原型给所有实例添加属性和方法.

+ +

属性

+ +
+
SyntaxError.prototype.constructor
+
创建实例的构造函数.
+
{{jsxref("Error.prototype.message", "SyntaxError.prototype.message")}}
+
错误信息. 尽管 ECMA-262 指出, {{jsxref("SyntaxError")}} 应该提供其子什么的信息属性,但在 SpiderMonkey 中, 仍是继承自{{jsxref("Error.prototype.message")}}.
+
{{jsxref("Error.prototype.name", "SyntaxError.prototype.name")}}
+
错误的名称.继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "SyntaxError.prototype.fileName")}}
+
抛出该异常的文件路径.继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "SyntaxError.prototype.lineNumber")}}
+
抛出该异常的文件的行号. 继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "SyntaxError.prototype.columnNumber")}}
+
抛出该异常的文件的列数. 继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "SyntaxError.prototype.stack")}}
+
栈追踪信息. 继承自 {{jsxref("Error")}}.
+
+ +

方法

+ +

尽管 {{jsxref("SyntaxError")}} 原型对象自身不包含任何方法,但 {{jsxref("SyntaxError")}} 实例从原型链中继承了一些方法.

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Defined as NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Defined as NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}Defined as NativeError.prototype.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/@@iterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/@@iterator/index.html new file mode 100644 index 0000000000..0d6556b0ca --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/@@iterator/index.html @@ -0,0 +1,125 @@ +--- +title: 'TypedArray.prototype[@@iterator]()' +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/@@iterator +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/@@iterator +--- +
{{JSRef}}
+ +

@@iterator 的初始值是和 {{jsxref("TypedArray.prototype.values()", "values")}} 属性的初始值相同的对象。

+ +

语法

+ +
arr[Symbol.iterator]()
+ +

返回值

+ +

数组的 迭代器 函数,通常是 {{jsxref("TypedArray.prototype.values()", "values()")}}函数。

+ +

示例

+ +

使用for...of 循环的迭代

+ +
var arr = new Uint8Array([10, 20, 30, 40, 50]);
+// 你的浏览器必须支持 for..of 循环
+// 以及 for 循环中的 let 区域变量
+for (let n of arr) {
+  console.log(n);
+}
+
+ +

备选迭代

+ +
var arr = new Uint8Array([10, 20, 30, 40, 50]);
+var eArr = arr[Symbol.iterator]();
+console.log(eArr.next().value); // 10
+console.log(eArr.next().value); // 20
+console.log(eArr.next().value); // 30
+console.log(eArr.next().value); // 40
+console.log(eArr.next().value); // 50
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-%typedarray%.prototype-@@iterator', '%TypedArray%.prototype[@@iterator]()')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype-@@iterator', '%TypedArray%.prototype[@@iterator]()')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown }}{{ CompatGeckoDesktop("36") }} [1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{ CompatVersionUnknown }}{{ CompatGeckoMobile("36") }} [1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] 从 Gecko 17 (Firefox 17 / Thunderbird 17 / SeaMonkey 2.14) 到 Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) 使用 iterator 属性 (bug 907077),从 Gecko 27 到 Gecko 35 使用"@@iterator" 占位符。 在 Gecko 36 (Firefox 36 / Thunderbird 36 / SeaMonkey 2.33)中,@@iterator Symbol 予以实现(bug 918828)。

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/@@species/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/@@species/index.html new file mode 100644 index 0000000000..816a29d721 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/@@species/index.html @@ -0,0 +1,126 @@ +--- +title: 'get TypedArray[@@species]' +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/@@species +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/@@species +--- +
{{JSRef}}
+ +

TypedArray[@@species] 访问器属性返回类型化数组的构造器。

+ +

语法

+ +
TypedArray[Symbol.species]
+
+其中TypedArray是下列类型之一:
+
+Int8Array
+Uint8Array
+Uint8ClampedArray
+Int16Array
+Uint16Array
+Int32Array
+Uint32Array
+Float32Array
+Float64Array
+
+ +

描述

+ +

species 访问器属性返回类型化数组对象的构造器。 子类的构造器可能会覆盖它来修改构造器的赋值。

+ +

示例

+ +

species 属性返回默认的构造器函数,对于给定的类型化数组对象,它是类型化数组构造器之一:

+ +
Int8Array[Symbol.species];    // function Int8Array()
+Uint8Array[Symbol.species];   // function Uint8Array()
+Float32Array[Symbol.species]; // function Float32Array()
+
+ +

在派生的集合对象中 (也就是你自己定义的类型化数组MyTypedArray), MyTypedArray 的 species 是 MyTypedArray 构造器。但是,你可能希望覆盖它,以便在你的派生类方法中返回类型化数组的基类对象:

+ +
class MyTypedArray extends Uint8Array {
+  // 将 MyTypedArray species 覆盖为 Uint8Array 基类构造器
+  static get [Symbol.species]() { return Uint8Array; }
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-%typedarray%-@@species', 'get %TypedArray% [ @@species ]')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-get-%typedarray%-@@species', 'get %TypedArray% [ @@species ]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("48")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("48")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/buffer/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/buffer/index.html new file mode 100644 index 0000000000..9affc3690f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/buffer/index.html @@ -0,0 +1,106 @@ +--- +title: TypedArray.prototype.buffer +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/buffer +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/buffer +--- +
{{JSRef}}
+ +

buffer访问器属性表示由TypedArray在构造期间引用的{{jsxref("ArrayBuffer")}}。

+ +

语法

+ +
typedArray.buffer
+ +

描述

+ +

buffer 属性是一个访问器属性,它的 set 访问器函数是undefined,意思是你只能够读取这个属性。它的值在TypedArray构造时建立,不能被修改。TypedArray是这里的类型化数组之一。

+ +

示例

+ +

使用 buffer 属性

+ +
var buffer = new ArrayBuffer(8);
+var uint16 = new Uint16Array(buffer);
+uint16.buffer; // ArrayBuffer { byteLength: 8 }
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-%typedarray%.prototype.buffer', 'TypedArray.prototype.buffer')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-get-%typedarray%.prototype.buffer', 'TypedArray.prototype.buffer')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support7.0{{ CompatGeckoDesktop("2") }}1011.65.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile("2") }}1011.64.2
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/bytelength/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/bytelength/index.html new file mode 100644 index 0000000000..7d09a0ec60 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/bytelength/index.html @@ -0,0 +1,113 @@ +--- +title: TypedArray.prototype.byteLength +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/byteLength +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/byteLength +--- +
{{JSRef}}
+ +

byteLength访问器属性表示类型化数组的长度(字节数)。

+ +

语法

+ +
typedarray.byteLength
+ +

描述

+ +

byteLength 是一个访问器属性,它的 set 访问器函数是undefined,意思是你只能够读取这个属性。它的值在TypedArray构造时建立,不能被修改。如果 TypedArray 没有指定byteOffset 或者 length,会返回所引用的ArrayBufferlengthTypedArray 是这里的 TypedArray 对象之一。

+ +

示例

+ +

使用byteLength 属性

+ +
var buffer = new ArrayBuffer(8);
+
+var uint8 = new Uint8Array(buffer);
+uint8.byteLength; // 8 (符合 buffer 的 byteLength)
+
+var uint8 = new Uint8Array(buffer, 1, 5);
+uint8.byteLength; // 5 (在 Uint8Array 构造时指定)
+
+var uint8 = new Uint8Array(buffer, 2);
+uint8.byteLength; // 6 (根据被构造的 Uint8Array 的 offset)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-%typedarray%.prototype.bytelength', 'TypedArray.prototype.byteLength')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-get-%typedarray%.prototype.bytelength', 'TypedArray.prototype.byteLength')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support7.0{{ CompatGeckoDesktop("2") }}1011.65.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.0{{CompatVersionUnknown}}{{CompatGeckoMobile("2")}}1011.64.2
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/byteoffset/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/byteoffset/index.html new file mode 100644 index 0000000000..dfbb599911 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/byteoffset/index.html @@ -0,0 +1,110 @@ +--- +title: TypedArray.prototype.byteOffset +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/byteOffset +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/byteOffset +--- +
{{JSRef}}
+ +

byteOffset 访问器属性表示类型化数组距离其{{jsxref("ArrayBuffer")}}起始位置的偏移(字节数)。

+ +

语法

+ +
typedarray.byteOffset
+ +

描述

+ +

byteOffset 是一个访问器属性,它的 set 访问器函数是undefined,意思是你只能够读取这个属性。它的值在TypedArray构造时建立,不能被修改。TypedArray 是这里的 TypedArray 对象之一。

+ +

示例

+ +

使用byteOffset 属性

+ +
var buffer = new ArrayBuffer(8);
+
+var uint8 = new Uint8Array(buffer);
+uint8.byteOffset; // 0 (没有指定 oddfet)
+
+var uint8 = new Uint8Array(buffer, 3);
+uint8.byteOffset; // 3 (在构造 Uint8Array 时指定)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-%typedarray%.prototype.byteoffset', 'TypedArray.prototype.byteOffset')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-get-%typedarray%.prototype.byteoffset', 'TypedArray.prototype.byteOffset')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support7.0{{ CompatGeckoDesktop("2") }}1011.65.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile("2") }}1011.64.2
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/bytes_per_element/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/bytes_per_element/index.html new file mode 100644 index 0000000000..4418eb2aab --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/bytes_per_element/index.html @@ -0,0 +1,115 @@ +--- +title: TypedArray.BYTES_PER_ELEMENT +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT +--- +
{{JSRef("Global_Objects", "TypedArray", "Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array")}}
+ +

概要

+ +

TypedArray.BYTES_PER_ELEMENT 属性代表了强类型数组中每个元素所占用的字节数。

+ +
{{js_property_attributes(0,0,0)}}
+ +

语法

+ +
TypedArray.BYTES_PER_ELEMENT;
+ +

描述

+ +

强类型数组对象用来解释为单个元素的字节数是不一样的。常量 BYTES_PER_ELEMENT 表示了特定强类型数组中每个元素所占用的字节数。

+ +

示例

+ +
Int8Array.BYTES_PER_ELEMENT;         // 1
+Uint8Array.BYTES_PER_ELEMENT;        // 1
+Uint8ClampedArray.BYTES_PER_ELEMENT; // 1
+Int16Array.BYTES_PER_ELEMENT;        // 2
+Uint16Array.BYTES_PER_ELEMENT;       // 2
+Int32Array.BYTES_PER_ELEMENT;        // 4
+Uint32Array.BYTES_PER_ELEMENT;       // 4
+Float32Array.BYTES_PER_ELEMENT;      // 4
+Float64Array.BYTES_PER_ELEMENT;      // 8
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
Typed Array Specification已过期被ECMAScript 6取代
{{SpecName('ES6', '#sec-typedarray.bytes_per_element', 'TypedArray.BYTES_PER_ELEMENT')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
功能ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持7.0{{ CompatGeckoDesktop("2") }}1011.65.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
功能AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持4.0{{ CompatVersionUnknown() }}{{ CompatGeckoMobile("2") }}1011.64.2
+
+ +

 

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/copywithin/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/copywithin/index.html new file mode 100644 index 0000000000..845b742ab4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/copywithin/index.html @@ -0,0 +1,128 @@ +--- +title: TypedArray.prototype.copyWithin() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin +tags: + - 类型化数组 + - 类型数组 +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin +--- +
{{JSRef}}
+ +

copyWithin() 方法将数组中元素的序列复制到以 target 起始的位置。拷贝的副本取自第二个参数(start)和第三个参数 (end)的下标位置。end 参数是可选的,默认为数组长度。该方法与 {{jsxref("Array.prototype.copyWithin")}} 的算法相同 TypedArray 指的是这里的 类型化数组类型 之一。

+ +

语法

+ +
typedarray.copyWithin(target, start[, end = this.length])
+ +

参数

+ +
+
target
+
目标起始位置的下标,复制元素到这里。
+
start
+
源起始位置的下标,在这里开始复制元素。
+
end {{optional_inline}}
+
可选。源终止位置的下标,在这里停止复制元素。
+
+ +

返回值

+ +

修改后的类型化数组。

+ +

描述

+ +

更多信息请见 {{jsxref("Array.prototype.copyWithin")}}。

+ +

这个方法取代了实验性的 {{jsxref("TypedArray.prototype.move()")}}。

+ +

示例

+ +
var buffer = new ArrayBuffer(8);
+var uint8 = new Uint8Array(buffer);
+uint8.set([1,2,3]);
+console.log(uint8); // Uint8Array [ 1, 2, 3, 0, 0, 0, 0, 0 ]
+uint8.copyWithin(3,0,3);
+console.log(uint8); // Uint8Array [ 1, 2, 3, 1, 2, 3, 0, 0 ]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-%typedarray%.prototype.copywithin', 'TypedArray.prototype.copyWithin')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.copywithin', 'TypedArray.prototype.copyWithin')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(45.0)}}{{CompatGeckoDesktop("34")}}{{CompatNo}} +

 {{CompatOpera(36.0)}}

+
{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("34")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/entries/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/entries/index.html new file mode 100644 index 0000000000..3dd4b5350d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/entries/index.html @@ -0,0 +1,124 @@ +--- +title: TypedArray.prototype.entries() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/entries +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/entries +--- +
{{JSRef}}
+ +

The entries()返回新的Array Iterator对象,包含数组每个下标处的键值对。

+ +

语法

+ +
arr.entries()
+ +

返回值

+ +

新的Array Iterator对象。

+ +

示例

+ +

使用for...of 循环的迭代

+ +
var arr = new Uint8Array([10, 20, 30, 40, 50]);
+var eArray = arr.entries();
+// 你的浏览器必须支持 for..of 循环
+// 以及 for 循环中的 let 区域变量
+for (let n of eArray) {
+  console.log(n);
+}
+
+ +

备选迭代

+ +
var arr = new Uint8Array([10, 20, 30, 40, 50]);
+var eArr = arr.entries();
+console.log(eArr.next().value); // [0, 10]
+console.log(eArr.next().value); // [1, 20]
+console.log(eArr.next().value); // [2, 30]
+console.log(eArr.next().value); // [3, 40]
+console.log(eArr.next().value); // [4, 50]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.entries', '%TypedArray%.prototype.entries()')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.entries', '%TypedArray%.prototype.entries()')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(45.0)}}{{CompatGeckoDesktop(37)}}{{CompatNo}}{{CompatOpera(36.0)}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{ CompatVersionUnknown }}{{CompatGeckoMobile(37)}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/every/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/every/index.html new file mode 100644 index 0000000000..6e6e1260ed --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/every/index.html @@ -0,0 +1,144 @@ +--- +title: TypedArray.prototype.every() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/every +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/every +--- +
{{JSRef}}
+ +

every() 方法测试类型化数组的所有元素是否都能够通过由提供函数实现的测试。这个方法的算法与 {{jsxref("Array.prototype.every()")}}相同。 TypedArray 是这里的 类型化数组类型 之一。

+ +

语法

+ +
typedarray.every(callback[, thisArg])
+ +

参数

+ +
+
callback
+
用于测试每个元素的函数,接受三个参数: +
+
currentValue
+
要处理的类型化数组的当前元素。
+
index
+
要处理的当前元素在类型化数组中的下标
+
array
+
every 在其上调用的类型化数组
+
+
+
thisArg
+
可选,执行 callback 时的 this 值。
+
+ +

返回值

+ +

如果函数对数组每个元素返回 {{Glossary("truthy")}} ,则为true,否则为 false

+ +

描述

+ +

every 方法为类型化数组中的每个元素执行一次 callback 函数,直到它找到一个使 callback 返回 false(表示可转换为布尔值 false 的值)的元素。如果发现了一个这样的元素,every 方法将会立即返回 false。否则,callback 为每一个元素返回 trueevery 就会返回 truecallback 只会为那些已经被赋值的索引调用。不会为那些被删除或从来没被赋值的索引调用。

+ +

callback 以三个参数调用:元素的值,元素索引,以及要遍历的数组对象。

+ +

如果将thisArg参数提供给every,它会在调用时传递给callback,作为它的 this值。否则,会传递undefined 作为它的this 值。  callback最终观测到的this值由 用于决定函数可见的this值的一般规则来决定。

+ +

every 不修改在其上调用的类型化数组。

+ +

示例

+ +

测试类型化数组所有元素的大小

+ +

下面的示例测试了类型化数组所有元素是否大于 10。

+ +
function isBigEnough(element, index, array) {
+  return element >= 10;
+}
+new Uint8Array([12, 5, 8, 130, 44]).every(isBigEnough);   // false
+new Uint8Array([12, 54, 18, 130, 44]).every(isBigEnough); // true
+ +

使用箭头函数测试类型化数组的元素

+ +

箭头函数为相同测试提供了更短的语法。

+ +
new Uint8Array([12, 5, 8, 130, 44]).every(elem => elem >= 10); // false
+new Uint8Array([12, 54, 18, 130, 44]).every(elem => elem >= 10); // true
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.every', 'TypedArray.prototype.every')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.every', 'TypedArray.prototype.every')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(45.0)}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatOpera(36.0)}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/fill/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/fill/index.html new file mode 100644 index 0000000000..3c89cc7f5b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/fill/index.html @@ -0,0 +1,134 @@ +--- +title: TypedArray.prototype.fill() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/fill +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/fill +--- +
{{JSRef}}
+ +

fill() 方法将类型化数组中的从起始索引到终止索引内的全部元素。这个方法的算法和 {{jsxref("Array.prototype.fill()")}} 相同。 TypedArray 是这里的类型化数组类型之一。

+ +

语法

+ +
typedarray.fill(value[, start = 0[, end = this.length]])
+ +

参数

+ +
+
value
+
用来填充类型化数组元素的值。
+
start
+
可选参数。起始索引,默认值为 0。
+
end
+
可选参数。终止索引(填充范围不包含此索引),默认值为 this.length
+
+ +

返回值

+ +

修改后的类型化数组。

+ +

描述

+ +

将被元素填充的区间是 [start, end)。

+ +

fill 方法接受三个参数 valuestart 以及 end。start 和 end 参数是可选的,默认值分别为 0this.length。

+ +

如果 start 参数是负值,它会被视为 length+start,其中 length 是类型化数组的长度。如果 end 参数是负值,它会被视为 length+end。

+ +

示例

+ +
new Uint8Array([1, 2, 3]).fill(4);         // Uint8Array [4, 4, 4]
+new Uint8Array([1, 2, 3]).fill(4, 1);      // Uint8Array [1, 4, 4]
+new Uint8Array([1, 2, 3]).fill(4, 1, 2);   // Uint8Array [1, 4, 3]
+new Uint8Array([1, 2, 3]).fill(4, 1, 1);   // Uint8Array [1, 2, 3]
+new Uint8Array([1, 2, 3]).fill(4, -3, -2); // Uint8Array [4, 2, 3]
+
+ +

兼容实现

+ +

由于并没有一个名为 TypedArray 的全局变量,我们必须“按需添加”兼容实现。请配合{{jsxref("Array.prototype.fill()")}}的兼容实现使用以下的“兼容实现”

+ +
// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.fill
+if (!Uint8Array.prototype.fill) {
+  Uint8Array.prototype.fill = Array.prototype.fill;
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ES2015', '#sec-%typedarray%.prototype.fill', 'TypedArray.prototype.fill')}}{{Spec2('ES2015')}}最初定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.fill', 'TypedArray.prototype.fill')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基础支持45{{CompatGeckoDesktop("37")}}{{CompatNo}}32{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础支持{{CompatNo}}{{CompatNo}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/filter/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/filter/index.html new file mode 100644 index 0000000000..59af0c38db --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/filter/index.html @@ -0,0 +1,145 @@ +--- +title: TypedArray.prototype.filter() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/filter +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/filter +--- +
{{JSRef}}
+ +

filter()创建新的类型化数组,含有所有通过了测试的元素,测试由提供的函数实现。这个方法的算法和 {{jsxref("Array.prototype.filter()")}}相同。 TypedArray 是这里的 类型化数组类型 之一。

+ +

语法

+ +
typedarray.filter(callback[, thisArg])
+ +

参数

+ +
+
callback
+
测试类型化数组每个元素的函数,以参数 (element, index, typedarray)调用。 如果返回 true则保留该元素,如果返回false则相反。
+
thisArg {{optional_inline}}
+
可选,执行callback时作为this的值。
+
+ +

返回值

+ +

新的类型化数组,含有通过测试的元素

+ +

描述

+ +

filter方法对类型化数组中的元素调用提供的 callback函数,并且会为callback返回 true 的那些元素构造新的类型化数组。 callback 只对拥有值的类型化数组下标调用。它不会对未定义的,被删除的或者没有赋值的下标调用。没有传给callback的类型化数组的元素只是简单跳过,不会包含在新数组中。

+ +

callback以三个参数调用:

+ +
    +
  1. 元素的值
  2. +
  3. 元素下标
  4. +
  5. 被遍历的类型化数组对象
  6. +
+ +

如果将thisArg参数提供给filter,它会在调用时传递给callback,作为它的 this值。否则,会传递undefined 作为它的this 值。  callback最终观测到的this值由 用于决定函数可见的this值的一般规则来决定。

+ +

filter()不改变在其上调用的类型化数组。

+ +

filter处理的元素范围在callback调用之前就确定了。 在 filter调用之后添加到数组的元素不会由 callback访问。 如果类型化数组的现有元素被改变,或被删除,它们传给callback的值是filter 访问它们时候的值。已删除的元素不会被访问。

+ +

示例

+ +

过滤所有较小的值

+ +

下面的示例使用了 filter() 来创建过滤后的类型化数组,小于 10 的元素都被移除了。

+ +
function isBigEnough(element, index, array) {
+  return element >= 10;
+}
+new Uint8Array([12, 5, 8, 130, 44]).filter(isBigEnough);
+// Uint8Array [ 12, 130, 44 ]
+
+ +

使用箭头函数过滤类型化数组的元素

+ +

箭头函数 为相同测试提供了更短的语法。

+ +
new Uint8Array([12, 5, 8, 130, 44]).filter(elem => elem >= 10);
+// Uint8Array [ 12, 130, 44 ]
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.filter', 'TypedArray.prototype.filter')}}{{Spec2('ES2015')}}初始定义
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.filter', 'TypedArray.prototype.filter')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("45")}}{{CompatGeckoDesktop("38")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("38")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/find/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/find/index.html new file mode 100644 index 0000000000..1b6b25c036 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/find/index.html @@ -0,0 +1,148 @@ +--- +title: TypedArray.prototype.find() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/find +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/find +--- +
{{JSRef}}
+ +

如果某个元素满足所提供的测试函数,find()方法返回类型化数组中的 。否则返回{{jsxref("undefined")}} 。 TypedArray 是这里的 类型化数组类型 之一。

+ +

同时请参见{{jsxref("TypedArray.findIndex", "findIndex()")}}方法,它返回了类型化数组中所发现元素的 下标 ,而不是它的值。

+ +

语法

+ +
typedarray.find(callback[, thisArg])
+ +

参数

+ +
+
callback
+
用于在类型化数组中的每个元素上执行的函数,接受三个参数: +
+
element
+
要处理的类型化数组的当前元素。
+
index
+
要处理的当前元素在类型化数组中的下标
+
array
+
find 在其上调用的类型化数组
+
+
+
thisArg
+
可选,执行callback时的this值。
+
+ +

返回值

+ +

如果元素通过了测试,则为该元素,否则为{{jsxref("undefined")}}。

+ +

描述

+ +

find 方法对类型化数组中的每个元素执行一次 callback 函数,直到它找到一个使 callback 返回 true的元素。如果发现了一个这样的元素,find 方法将会立即返回该元素的值。否则,find 方法会返回{{jsxref("undefined")}}。callback 只会对那些已经被赋值的索引调用。不会对那些被删除或从来没被赋值的索引调用。

+ +

callback 以三个参数调用:元素的值,元素索引,以及要遍历的数组对象。

+ +

如果将thisArg参数提供给find,它会在调用时传递给callback,作为它的 this值。如果没有提供,会使用undefined

+ +

find 不修改在其上调用的类型化数组。

+ +

find处理的元素范围在callback调用之前就确定了。 在 find调用之后添加到数组的元素不会由 callback访问。 如果类型化数组的现有元素被改变,或被删除,它们传给callback的值是find 访问它们时候的值。已删除的元素不会被访问。

+ +

示例

+ +

在类型化数组中寻找质数

+ +

下面的示例在类型化数组中寻找质数(如果没有质数则返回 undefined)。

+ +
function isPrime(element, index, array) {
+  var start = 2;
+  while (start <= Math.sqrt(element)) {
+    if (element % start++ < 1) {
+      return false;
+    }
+  }
+  return element > 1;
+}
+
+var uint8 = new Uint8Array([4, 5, 8, 12]);
+console.log(uint8.find(isPrime)); // 5
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.find', '%TypedArray%.prototype.find')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.find', '%TypedArray%.prototype.find')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatGeckoDesktop("37.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("37.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/findindex/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/findindex/index.html new file mode 100644 index 0000000000..4ebcc0d816 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/findindex/index.html @@ -0,0 +1,188 @@ +--- +title: TypedArray.prototype.findIndex() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/findIndex +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/findIndex +--- +
{{JSRef}}
+ +

如果某个元素满足所提供的测试函数,findIndex()方法返回类型化数组中的 下标。否则返回 -1。 TypedArray 是这里的 类型化数组类型 之一。

+ +

同时请参见{{jsxref("TypedArray.findIndex", "find()")}}方法,它返回了类型化数组中所发现元素的 ,而不是它的下标。

+ +

语法

+ +
typedarray.findIndex(callback[, thisArg])
+ +

参数

+ +
+
callback
+
用于在类型化数组中的每个元素上执行的函数,接受三个参数: +
+
element
+
要处理的类型化数组的当前元素。
+
index
+
要处理的当前元素在类型化数组中的下标
+
array
+
find 在其上调用的类型化数组
+
+
+
thisArg
+
可选,执行callback时的this值。
+
+ +

返回值

+ +

如果元素通过了测试,则为数组下标,否则为 -1。

+ +

描述

+ +

findIndex 方法对类型化数组中的每个元素执行一次 callback 函数,直到它找到一个使 callback 返回 true的元素。如果发现了一个这样的元素,find 方法将会立即返回该元素的下标。否则,findIndex 方法会返回 -1。callback 只会对那些已经被赋值的索引调用。不会对那些被删除或从来没被赋值的索引调用。

+ +

callback 以三个参数调用:元素的值,元素索引,以及要遍历的数组对象。

+ +

如果将thisArg参数提供给findIndex,它会在调用时传递给callback,作为它的 this值。如果没有提供,会使用undefined

+ +

findIndex 不修改在其上调用的类型化数组。

+ +

findIndex处理的元素范围在callback调用之前就确定了。 在 findIndex调用之后添加到数组的元素不会由 callback访问。 如果类型化数组的现有元素被改变,或被删除,它们传给callback的值是findIndex 访问它们时候的值。已删除的元素不会被访问。

+ +

示例

+ +

在类型化数组中寻找质数的下标

+ +

下面的示例在类型化数组中寻找质数元素的下标(如果没有质数则返回 -1).

+ +
function isPrime(element, index, array) {
+  var start = 2;
+  while (start <= Math.sqrt(element)) {
+    if (element % start++ < 1) {
+      return false;
+    }
+  }
+  return element > 1;
+}
+
+var uint8 = new Uint8Array([4, 6, 8, 12]);
+var uint16 = new Uint16Array([4, 6, 7, 12]);
+
+console.log(uint8.findIndex(isPrime)); // -1, 未发现
+console.log(uint16.findIndex(isPrime)); // 2
+
+ +

Polyfill

+ +
TypedArray.prototype.findIndex = Array.prototype.findIndex = Array.prototype.findIndex || function(evaluator, thisArg) {
+        'use strict';
+        if (!this) {
+          throw new TypeError('Array.prototype.some called on null or undefined');
+        }
+
+        if (typeof(evaluator) !== 'function') {
+            if (typeof(evaluator) === 'string') {
+                // 尝试将其转换为函数
+                if ( ! (evaluator = eval(evaluator)) ){
+                    throw new TypeError();
+                }
+            } else {
+                throw new TypeError();
+            }
+        }
+
+        var i;
+        if (thisArg === undefined) {  // 为 thisArg 优化
+            for (i in this) {
+                if (evaluator(this[i], i, this)) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+        for (i in this) {
+            if (evaluator.call(thisArg, this[i], i, this)) {
+                return i;
+            }
+        }
+        return -1;
+};
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.findindex', '%TypedArray%.prototype.findIndex')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.findindex', '%TypedArray%.prototype.findIndex')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatGeckoDesktop("37.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("37.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/foreach/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/foreach/index.html new file mode 100644 index 0000000000..801df8bed5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/foreach/index.html @@ -0,0 +1,111 @@ +--- +title: TypedArray.prototype.forEach() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/forEach +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/forEach +--- +
{{JSRef}}
+ +

forEach()方法对类型化数组的每个元素调用提供的函数。 这个方法的算法和 {{jsxref("Array.prototype.forEach()")}}相同。 TypedArray 是这里的 类型化数组类型 之一。

+ +

语法

+ +
typedarray.forEach(callback[, thisArg])
+ +

参数

+ +
+
callback
+
产生新的类型化数组的元素的函数,接受三个函数: +
+
currentValue
+
类型化数组中要处理的当前元素
+
index
+
类型化数组中要处理的当前元素的下标
+
array
+
forEach()在其上调用的类型化数组
+
+
+
thisArg
+
可选,执行callback时作为this的值。
+
+ +

返回值

+ +

{{jsxref("undefined")}}.

+ +

描述

+ +

forEach方法对类型化数组中的元素按升序调用提供的 callback函数。 它不会对删除或者省略的下标调用,但是会对存在并且值为{{jsxref("undefined")}}的元素调用。

+ +

callback三个参数调用:

+ + + +

如果将thisArg参数提供给forEach,它会在调用时传递给callback,作为它的 this值。否则,会传递undefined 作为它的this 值。  callback最终观测到的this值由 用于决定函数可见的this值的一般规则来决定。

+ +

forEach处理的元素范围在callback调用之前就确定了。 在 forEach调用之后添加到数组的元素不会由 callback访问。 如果类型化数组的现有元素被改变,或被删除,它们传给callback的值是forEach 访问它们时候的值。已删除的元素不会被访问。

+ +

forEach()对每个数组元素执行一次callback 函数;不像 {{jsxref("TypedArray.prototype.every()", "every()")}} 和{{jsxref("TypedArray.prototype.some()", "some()")}},它始终返回 {{jsxref("undefined")}}。

+ +

示例

+ +

记录类型化数组的内容

+ +

下面的代码为数组中的每个元素记录一行日志:

+ +
function logArrayElements(element, index, array) {
+  console.log('a[' + index + '] = ' + element);
+}
+
+new Uint8Array([0, 1, 2, 3]).forEach(logArrayElements);
+// 日志:
+// a[0] = 0
+// a[1] = 1
+// a[2] = 2
+// a[3] = 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.foreach', '%TypedArray%.prototype.forEach')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.foreach', '%TypedArray%.prototype.forEach')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + +

{{Compat("javascript.builtins.TypedArray.forEach")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/from/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/from/index.html new file mode 100644 index 0000000000..20bdbf8b7f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/from/index.html @@ -0,0 +1,183 @@ +--- +title: TypedArray.from() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/from +tags: + - from + - 类型数组 +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/from +--- +
{{JSRef}}
+ +

TypedArray.from() 方法 从一个类数组或者可迭代对象中创建一个新类型数组。 这个方法和 {{jsxref("Array.from()")}} 类似。

+ +

语法

+ +
TypedArray.from(source[, mapFn[, thisArg]])
+
+ +

上面代码中的 TypedArray 需要替换为下面的任何一个构造函数:

+ +
+ +
+ +

参数

+ +
+
source
+
想要转换为类型数组的类数组或者可迭代对象。
+
mapFn
+
可选参数。如果指定了该参数,则最后生成的类型数组会经过该函数的加工处理后再返回。
+
thisArg
+
可选参数。执行 mapFn 函数时 this 的值。
+
+ +

返回值

+ +

一个新的 {{jsxref("TypedArray")}} 实例。

+ +

 描述

+ +

TypedArray.from() 允许你从下面两者来创建数组:

+ + + +

TypedArray.from() 方法有一个可选参数 mapFn, 让你可以在最后生成的类型数组上再执行一次 {{jsxref("Array.prototype.map", "map")}} 方法后再返回。也就是说以下两种形式是等价的:

+ + + +

 from() 的 length 属性值为 1

+ +

{{jsxref("Array.from()")}} 和 TypedArray.from() 之间有一些微妙的区别:

+ + + +

示例

+ +
// 使用 Set (可迭代对象)
+var s = new Set([1, 2, 3]);
+Uint8Array.from(s);
+// Uint8Array [ 1, 2, 3 ]
+
+
+// 使用字符串
+Int16Array.from('123');
+// Int16Array [ 1, 2, 3 ]
+
+
+// 使用箭头函数对数组元素进行映射
+Float32Array.from([1, 2, 3], x => x + x);
+// Float32Array [ 2, 4, 6 ]
+
+
+// 生成一个数字序列
+Uint8Array.from({length: 5}, (v, k) => k);
+// Uint8Array [ 0, 1, 2, 3, 4 ]
+
+ +

Polyfill 

+ +

在不支持 from() 的环境中,你可以在你代码的起始位置插入以下代码,来实现对其功能的大部分支持。

+ +
if (!Int8Array.__proto__.from) {
+    (function () {
+        Int8Array.__proto__.from = function (obj, func, thisObj) {
+
+            var typedArrayClass = Int8Array.__proto__;
+            if(typeof this !== 'function') {
+                throw new TypeError('# is not a constructor');
+            }
+            if (this.__proto__ !== typedArrayClass) {
+                throw new TypeError('this is not a typed array.');
+            }
+
+            func = func || function (elem) {
+                    return elem;
+                };
+
+            if (typeof func !== 'function') {
+                throw new TypeError('specified argument is not a function');
+            }
+
+            obj = Object(obj);
+            if (!obj['length']) {
+                return new this(0);
+            }
+            var copy_data = [];
+            for(var i = 0; i < obj.length; i++) {
+                copy_data.push(obj[i]);
+            }
+
+            copy_data = copy_data.map(func, thisObj);
+
+            var typed_array = new this(copy_data.length);
+            for(var i = 0; i < typed_array.length; i++) {
+                typed_array[i] = copy_data[i];
+            }
+            return typed_array;
+        }
+    })();
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.from', '%TypedArray%.from')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-%typedarray%.from', '%TypedArray%.from')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.TypedArray.from")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/includes/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/includes/index.html new file mode 100644 index 0000000000..9496cdc621 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/includes/index.html @@ -0,0 +1,122 @@ +--- +title: TypedArray.prototype.includes() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/includes +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/includes +--- +
{{JSRef}}
+ +

includes()方法判断类型化数组中是否含有特定元素,并相应返回true 或者false ,这个方法的算法和{{jsxref("Array.prototype.includes()")}}相同。 TypedArray 是这里的 类型化数组 之一。

+ +

语法

+ +
typedarray.includes(searchElement[, fromIndex]);
+ +

参数

+ +
+
searchElement
+
要搜索的元素。
+
fromIndex
+
可选,数组中的位置,在这里开始搜索 searchElement;默认为 0。
+
+ +

返回值

+ +

{{jsxref("Boolean")}}。

+ +

示例

+ +
var uint8 = new Uint8Array([1,2,3]);
+uint8.includes(2);     // true
+uint8.includes(4);     // false
+uint8.includes(3, 3);  // false
+
+// NaN 的处理 (仅仅对 Float32 和 Float64 为 true)
+new Uint8Array([NaN]).includes(NaN); // false, 因为 NaN 传递给构造器时转换为 0
+new Float32Array([NaN]).includes(NaN); // true;
+new Float64Array([NaN]).includes(NaN); // true;
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES7', '#sec-%typedarray%.prototype.includes', 'TypedArray.prototype.includes')}}{{Spec2('ES7')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.includes', 'TypedArray.prototype.includes')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)EdgeInternet ExplorerOperaSafari
Basic support474314{{CompatNo}}3410
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}4743{{CompatNo}}3410
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/index.html new file mode 100644 index 0000000000..3ccd0fd6f2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/index.html @@ -0,0 +1,307 @@ +--- +title: TypedArray +slug: Web/JavaScript/Reference/Global_Objects/TypedArray +tags: + - JavaScript + - TypedArray + - 类型化数组 + - 类型数组 + - 缓冲区 +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray +--- +

{{JSRef}}

+ +

一个类型化数组TypedArray)对象描述了一个底层的二进制数据缓冲区(binary data buffer)的一个类数组视图(view)。事实上,没有名为 TypedArray 的全局属性,也没有一个名为 TypedArray 的构造函数。相反,有许多不同的全局属性,它们的值是特定元素类型的类型化数组构造函数,如下所示。在下面的页面中,你会发现一些,与包含任何类型的元素的任意类型化数组一起使用的通用属性和方法。

+ +
{{EmbedInteractiveExample("pages/js/typedarray-constructor.html")}}
+ + + +

语法

+ +
// 下面代码是语法格式,不能直接运行,
+// TypedArray 关键字需要替换为底部列出的构造函数。
+new TypedArray(); // ES2017中新增
+new TypedArray(length);
+new TypedArray(typedArray);
+new TypedArray(object);
+new TypedArray(buffer [, byteOffset [, length]]);
+
+// TypedArray 指的是以下的其中之一:
+
+Int8Array();
+Uint8Array();
+Uint8ClampedArray();
+Int16Array();
+Uint16Array();
+Int32Array();
+Uint32Array();
+Float32Array();
+Float64Array();
+ +

参数

+ +
+
length
+
当传入 length 参数时,一个内部的数组缓冲区会被创建在内存中,该缓存区的大小(类型化数组中 byteLength 属性的值)是传入的 length 乘以数组中每个元素的字节数(BYTES_PER_ELEMENT),每个元素的值都为0。(译者注:每个元素的字节数是由具体的构造函数决定的,比如 Int16Array() 的每个元素的字节数为 2Int32Array() 的每个元素的字节数为 4)
+
typedArray
+
当传入一个任意类型化数组对象作为 typedArray 参数时(比如 Int32Array),typedArray 会被复制到一个新的类型数组中。typedArray 中的每个值在被复制到新的数组之前,会被转化为相应类型的构造函数。新的生成的类型化数组对象将会有跟传入的数组相同的长度(译者注:比如原来的类型化数组的 length==2,那么新生成的数组的 length 也是 2,只是数组中的每一项进行了转化)。
+
object
+
+

当传入一个 object 作为参数时,就像通过 TypedArray.from() 方法创建一个新的类型化数组一样。

+
+
bufferbyteOffset, length
+
当传入一个 buffer 参数,或者再另外加上可选参数 byteOffset 和 length 时,一个新的类型化数组视图将会被创建,并可用于呈现传入的 ArrayBuffer 实例。byteOffset 和length 参数指定了类型化数组视图将要暴露的内存范围。如果两者都未传入,那么整个buffer 都会被呈现;如果仅仅忽略 length,那么 buffer 中偏移了 byteOffset 后剩下的 buffer 将会被呈现。
+
+ +

描述

+ +

ECMAScript 2015 定义了一个 TypeArray 构造器作为所有的类型化数组构造器(Int8Array, Int16Array 等)的原型([[Prototype]])。该构造器并不会直接暴露出来:即没有全局的 %TypedArray% 和 TypeArray 属性,只能通过使用类似于 Object.getPrototypeOf(Int8Array.prototype) 的方式直接访问。所有的类型化数组构造器都会继承 %TypeArray% 构造器函数的公共属性和方法。此外,所有的类型化数组的原型(如 Int8Array.prototype)都以 %TypeArray%.prototype 作为原型。

+ +

%TypedArray% 构造器自身不是特别有用,直接调用或使用 new 表达式实例化都会抛出一个{{jsxref("TypeError")}} 异常,除非在支持子类化(subclassing)创建对象的 JS 引擎下运行。但直到现在还没有这样的 JS 引擎出现。因此 %TypeArray% 仅仅在对所有的类型化数组构造器(Int8Array 等)的方法和属性进行 polyfill 的时候比较有用.

+ +

当创建一个 TypedArray 实例(如 Int8Array)时,一个数组缓冲区将被创建在内存中,如果一个 ArrayBuffer 对象被当作参数传给构造函数,那么将使用传入的 ArrayBuffer 代替(即缓冲区被创建到 ArrayBuffer 中)。缓冲区的地址被存储在实例的内部属性中,并且所有 %TypedArray%.prototype上的方法,例如 set valueget value 等,都会在这个数组缓冲区上进行操作。

+ +

属性访问

+ +

你可以使用标准数组索引语法获取类型化数组中的元素(也就是和访问普通数组元素一样,如 foo[1]),然而,在类型化数组上获取或者设置属性的值时,并不会在这个属性的原型链中进行搜索,即使在索引超出了边界的时候。在原型中添加的属性将会在 {{jsxref("ArrayBuffer")}} 中查询而不是在对象的属性中。但是你依然可以像其他对象一样使用命名的属性来访问(foo.bar 的形式);具体见下面的例子:

+ +
// 使用标准数组语法来获取和设置属性值
+var int16 = new Int16Array(2);
+int16[0] = 42;
+console.log(int16[0]); // 42
+
+// 原型中添加的属性访问不到(此时索引值未超边界,20 < 32)
+Int8Array.prototype[20] = "foo";
+(new Int8Array(32))[20]; // 0
+
+// 即使索引值超出了边界也一样不能访问(20 > 8)
+Int8Array.prototype[20] = "foo";
+(new Int8Array(8))[20]; // undefined
+
+// 使用负数索引也不行
+Int8Array.prototype[-1] = "foo";
+(new Int8Array(8))[-1]; // undefined
+
+// 但是可以使用命名属性的方式访问到
+Int8Array.prototype.foo = "bar";
+(new Int8Array(32)).foo; // "bar"
+ +

TypedArray 对象

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
类型单个元素值的范围大小(bytes)描述Web IDL 类型C 语言中的等价类型
{{jsxref("Int8Array")}}-128 to 12718 位二进制有符号整数byteint8_t
{{jsxref("Uint8Array")}}0 to 25518 位无符号整数(超出范围后从另一边界循环)octetuint8_t
{{jsxref("Uint8ClampedArray")}}0 to 25518 位无符号整数(超出范围后为边界值)octetuint8_t
{{jsxref("Int16Array")}}-32768 to 32767216 位二进制有符号整数shortint16_t
{{jsxref("Uint16Array")}}0 to 65535216 位无符号整数unsigned shortuint16_t
{{jsxref("Int32Array")}}-2147483648 to 2147483647432 位二进制有符号整数longint32_t
{{jsxref("Uint32Array")}}0 to 4294967295432 位无符号整数unsigned longuint32_t
{{jsxref("Float32Array")}}1.2×10-38 to 3.4×1038432 位 IEEE 浮点数(7 位有效数字,如 1.1234567unrestricted floatfloat
{{jsxref("Float64Array")}}5.0×10-324 to 1.8×10308864 位 IEEE 浮点数(16 有效数字,如 1.123...15)unrestricted doubledouble
{{jsxref("BigInt64Array")}}-263 to 263-1864 位二进制有符号整数bigintint64_t (signed long long)
{{jsxref("BigUint64Array")}}0 to 264-1864 位无符号整数bigintuint64_t (unsigned long long)
+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT")}}
+
返回一个数值,代表不同类型的类型化数组对象中,单个元素的字节大小。例如 new Int8Array().BYTES_PER_ELEMENT === 1, new Int16Array().BYTES_PER_ELEMENT === 2 ( 8 位字节为 1,16 位为 2 字节,类推)。   
+
TypedArray.length
+
类型化数组中元素的个数,例如 new Int8Array(3).length === 3
+
{{jsxref("TypedArray.name")}}
+
返回一个字符串值,代表当前构造器的名称,例如 "Int8Array"
+
{{jsxref("TypedArray.@@species", "get TypedArray[@@species]")}}
+
用于创建派生对象的构造函数函数。
+
{{jsxref("TypedArray.prototype")}}
+
TypedArray 对象的原型。
+
+ +

方法

+ +
+
{{jsxref("TypedArray.from()")}}
+
使用类数组(array-like)或迭代对象创建一个新的类型化数组.参见 {{jsxref("Array.from()")}}.
+
{{jsxref("TypedArray.of()")}}
+
通过可变数量的参数创建新的类型化数组.参见 {{jsxref("Array.of()")}}.
+
+ +

TypedArray 原型

+ +

所有的类型化数组都继承自 {{jsxref("TypedArray.prototype")}}.

+ +

属性

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/TypedArray/prototype','属性')}}

+ +

方法

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/TypedArray/prototype','methods')}}

+ +

方法的 Polyfill

+ +

大部分 TypedArrays 中的方法可以使用 JavaScript 中的普通数组中存在的方法来实现。

+ +

下面的 JavaScript 代码片段,可能会是你尝试用来补救 TypedArray 方法缺失的手段(polyfill):

+ +
var typedArrayTypes = [Int8Array, Uint8Array, Uint8ClampedArray,
+                       Int16Array, Uint16Array, ​​​Int32Array,
+                       Uint32Array, ​​​Float32Array, Float64Array];
+
+for (var k in typedArrayTypes)
+    for (var v in Array.prototype)
+        if (Array.prototype.hasOwnProperty(v) &&
+          !typedArrayTypes[k].prototype.hasOwnProperty(v))
+            typedArrayTypes[k].prototype[v] = Array.prototype[v];
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Defined as TypedArray and ArrayBufferView interface with typed array view types. Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-typedarray-objects', 'TypedArray Objects')}}{{Spec2('ES6')}}Initial definition in an ECMA standard. Specified behaviour for indexed and named properties. Specified that new is required.
{{SpecName('ESDraft', '#sec-typedarray-objects', 'TypedArray Objects')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ +

{{Compat("javascript.builtins.TypedArray")}}

+ +

兼容性注意事项

+ +

从ECMAScript 2015 (ES6) 开始,TypedArray 构造函数使用的时候必须要使用 new 操作符,否则会抛出 {{jsxref("TypeError")}} 异常。

+ +
var dv = Int8Array([1, 2, 3]);
+// TypeError: calling a builtin Int8Array constructor 
+ +
var dv = new Int8Array([1, 2, 3]);
+ +

相关链接

+ + + +

+ +

+ +

+ +

+ +

+ +

diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/indexof/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/indexof/index.html new file mode 100644 index 0000000000..b7893c25f8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/indexof/index.html @@ -0,0 +1,132 @@ +--- +title: TypedArray.prototype.indexOf() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/indexOf +tags: + - TypedArray + - Uint8Array +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/indexOf +--- +
{{JSRef}}
+ +

indexOf() 方法返回在类型数组中可以找到给定元素的第一个索引,如果不存在,则返回-1。 方法具有与 {{jsxref("Array.prototype.indexOf()")}} 相同的算法。 TypedArray是这里的类型化数组类型之一。

+ +

语法

+ +
typedarray.indexOf(searchElement[, fromIndex = 0])
+ +

参数

+ +
+
searchElement
+
需要在类型化数组中定位的元素
+
fromIndex
+
搜索的起始下标。如果下标大于等于类型化数组长度,则返回 -1,意思是类型化数组不会被搜索。如果提供的下标值是负数,则被当做距离类型化数组尾部的偏移。注:如果提供的下标是负数,类型化数组仍然从前到后搜索。如果计算出来的下标小于 0,则会搜索整个类型化数组。默认为 0(搜索整个类型化数组)。
+
+ +

返回值

+ +

数组中元素的第一个下标;没有找到则返回-1

+ +

描述

+ +

indexOf使用严格相等 (由 === 或三等号运算符使用的相同方法)比较searchElement和类型化数组的元素。

+ +

示例

+ +
let uint8 = new Uint8Array([2, 5, 9]);
+uint8.indexOf(2);     // 0
+uint8.indexOf(7);     // -1
+uint8.indexOf(9, 2);  // 2
+uint8.indexOf(2, -1); // -1
+uint8.indexOf(2, -3); // 0
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-%typedarray%.prototype.indexof', 'TypedArray.prototype.indexOf')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.indexof', 'TypedArray.prototype.indexOf')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("45")}}{{CompatVersionUnknown}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatChrome("32")}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

兼容性注解

+ + + +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/join/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/join/index.html new file mode 100644 index 0000000000..31dbcc2ae1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/join/index.html @@ -0,0 +1,128 @@ +--- +title: TypedArray.prototype.join() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/join +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/join +--- +
{{JSRef}}
+ +

join()方法将数组中所有元素连接为一个字符串。这个方法的算法和{{jsxref("Array.prototype.join()")}}相同。 TypedArray 是这里的 类型化数组 之一。

+ +

语法

+ +
typedarray.join([separator = ',']);
+ +

参数

+ +
+
separator
+
可选。指定分隔每个元素的字符串。分隔符按需转换为字符串。如果没有,类型化数组的元素会以逗号(",")分隔。
+
+ +

返回值

+ +

所有元素连接后的字符串。

+ +

示例

+ +
var uint8 = new Uint8Array([1,2,3]);
+uint8.join();      // '1,2,3'
+uint8.join(' / '); // '1 / 2 / 3'
+uint8.join('');    // '123'
+
+ +

Polyfill

+ +

由于没有名为TypedArray的全局元素,polyfill 必须"按情况"实现。

+ +
// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.join
+if (!Uint8Array.prototype.join) {
+  Object.defineProperty(Uint8Array.prototype, 'join', {
+    value: Array.prototype.join
+  });
+}
+
+ +

如果你需要支持过时的 JavaScript 引擎,它们不支持Object.defineProperty,最好不要 polyfill Array.prototype 方法,因为你不能使它们不可枚举。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.join', 'TypedArray.prototype.join')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.join', 'TypedArray.prototype.join')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("37")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/keys/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/keys/index.html new file mode 100644 index 0000000000..dbed46268a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/keys/index.html @@ -0,0 +1,128 @@ +--- +title: TypedArray.prototype.keys() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/keys +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/keys +--- +
{{JSRef}}
+ +

keys()方法返回新的 Array Iterator 对象,包含数组中每个下标的键。

+ +

语法

+ +
arr.keys()
+ +

返回值

+ +

新的Array Iterator对象

+ +

示例

+ +

使用for...of循环的迭代

+ +
var arr = new Uint8Array([10, 20, 30, 40, 50]);
+var eArray = arr.keys();
+// 你的浏览器必须支持 for..of 循环
+// 以及 for 循环中的 let 区域变量
+for (let n of eArray) {
+  console.log(n);
+}
+
+ +

备选的迭代

+ +
var arr = new Uint8Array([10, 20, 30, 40, 50]);
+var eArr = arr.keys();
+console.log(eArr.next().value); // 0
+console.log(eArr.next().value); // 1
+console.log(eArr.next().value); // 2
+console.log(eArr.next().value); // 3
+console.log(eArr.next().value); // 4
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.keys', '%TypedArray%.prototype.keys()')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.keys', '%TypedArray%.prototype.keys()')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoDesktop(37)}}{{CompatNo}}{{CompatNo}}10
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatGeckoMobile(37)}}{{CompatNo}}{{CompatNo}}10
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/lastindexof/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/lastindexof/index.html new file mode 100644 index 0000000000..8552cf0dae --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/lastindexof/index.html @@ -0,0 +1,130 @@ +--- +title: TypedArray.prototype.lastIndexOf() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/lastIndexOf +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/lastIndexOf +--- +
{{JSRef}}
+ +

lastIndexOf() 方法返回在类型数组中可以找到给定元素的最后一个索引,如果不存在,则返回-1。 方法具有与 {{jsxref("Array.prototype.lastIndexOf()")}} 相同的算法。 TypedArray是这里的类型化数组类型之一。

+ +

语法

+ +
typedarray.lastIndexOf(searchElement[, fromIndex = typedarray.length])
+ +

参数

+ +
+
searchElement
+
需要在类型化数组中定位的元素
+
fromIndex
+
可选。反向搜索的起始下标。默认为数组的长度,即会搜索整个类型化数组。如果下标大于等于类型化数组长度,会搜索整个类型化数组。如果是负数,则被当做距离类型化数组尾部的偏移。注:如果提供的下标是负数,类型化数组仍然从后到前搜索。如果计算出来的下标小于 0,则会返回 -1,即不会搜索类型化数组。
+
+ +

返回值

+ +

数组中元素的最后一个下标;没有找到则返回 -1

+ +

描述

+ +

lastIndexOf使用严格相等 (由 === 或三等号运算符使用的相同方法)比较searchElement和类型化数组的元素。

+ +

示例

+ +
var uint8 = new Uint8Array([2, 5, 9, 2]);
+uint8.lastIndexOf(2);     // 3
+uint8.lastIndexOf(7);     // -1
+uint8.lastIndexOf(2, 3);  // 3
+uint8.lastIndexOf(2, 2);  // 0
+uint8.lastIndexOf(2, -2); // 0
+uint8.lastIndexOf(2, -1); // 3
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.lastindexof', 'TypedArray.prototype.lastIndexOf')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.lastindexof', 'TypedArray.prototype.lastIndexOf')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatVersionUnknown}}10
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatNo}}10
+
+ +

兼容性注解

+ + + +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/length/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/length/index.html new file mode 100644 index 0000000000..0db01b1d09 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/length/index.html @@ -0,0 +1,113 @@ +--- +title: TypedArray.prototype.length +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/length +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/length +--- +
{{JSRef}}
+ +

length访问器属性表示类型化数组的长度(元素数)。

+ +

语法

+ +
typedarray.length
+ +

描述

+ +

length 是一个访问器属性,它的 set 访问器函数是undefined,意思是你只能够读取这个属性。它的值在TypedArray构造时建立,不能被修改。如果 TypedArray 没有指定byteOffset 或者 length,会返回所引用的ArrayBufferlengthTypedArray 是这里的 TypedArray 对象之一。

+ +

示例

+ +

使用length 属性

+ +
var buffer = new ArrayBuffer(8);
+
+var uint8 = new Uint8Array(buffer);
+uint8.length; // 8 (符合 buffer 的 length)
+
+var uint8 = new Uint8Array(buffer, 1, 5);
+uint8.length; // 5 (在 Uint8Array 构造时指定)
+
+var uint8 = new Uint8Array(buffer, 2);
+uint8.length; // 6 (根据被构造的 Uint8Array 的 offset)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-get-%typedarray%.prototype.length', 'TypedArray.prototype.length')}}{{Spec2('ES6')}}初始定义
{{SpecName('ESDraft', '#sec-get-%typedarray%.prototype.length', 'TypedArray.prototype.length')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support7.0{{CompatGeckoDesktop("2")}}1011.65.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.0{{CompatVersionUnknown}}{{CompatGeckoMobile("2")}}1011.64.2
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/map/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/map/index.html new file mode 100644 index 0000000000..b32a447ca3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/map/index.html @@ -0,0 +1,151 @@ +--- +title: TypedArray.prototype.map() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/map +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/map +--- +
{{JSRef}}
+ +

map()方法对类型化数组的每个元素调用提供的函数,并使用结果来创建新的类型化数组。 这个方法的算法和 {{jsxref("Array.prototype.map()")}}相同。 TypedArray 是这里的 类型化数组类型 之一。

+ +

语法

+ +
typedarray.map(callback[, thisArg])
+ +

参数

+ +
+
callback
+
产生新的类型化数组的元素的函数,接受三个函数: +
+
currentValue
+
类型化数组中要处理的当前元素
+
index
+
类型化数组中要处理的当前元素的下标
+
array
+
map在其上调用的类型化数组
+
+
+
thisArg
+
可选,执行callback时作为this的值。
+
+ +

返回值

+ +

新的类型化数组

+ +

描述

+ +

map方法对类型化数组中的元素调用提供的 callback函数,按照顺序,并且会从结果构造新的类型化数组。 callback 只对拥有值的类型化数组下标调用。它不会对未定义的,被删除的或者没有赋值的下标调用。

+ +

callback 以三个参数调用: 元素的值,元素下标,和被遍历的类型化数组。

+ +

如果将thisArg参数提供给map,它会在调用时传递给callback,作为它的 this值。否则,会传递undefined 作为它的this 值。  callback最终观测到的this值由 用于决定函数可见的this值的一般规则来决定。

+ +

map 不改变在其上调用的类型化数组(虽然如果调用了callback可能会这样做)。

+ +

map处理的元素范围在callback调用之前就确定了。 在 map调用之后添加到数组的元素不会由 callback访问。 如果类型化数组的现有元素被改变,或被删除,它们传给callback的值是map 访问它们时候的值。已删除的元素不会被访问。

+ +

示例

+ +

将类型数组映射被平方根的类型数组

+ +

下面的代码接受一个类型数组,并创建一个新的类型数组,含有第一个类型数组中元素的平方根。

+ +
var numbers = new Uint8Array([1, 4, 9]);
+var roots = numbers.map(Math.sqrt);
+// roots is now: Uint8Array [1, 2, 3],
+// numbers is still Uint8Array [1, 4, 9]
+
+ +

使用含有参数的函数来映射类型数组

+ +

下面的代码展示了,当使用需要一个参数的函数时,map的工作方式。在map遍历原始数组的过程中,参数会自动赋值为类型化数组的每个元素。

+ +
var numbers = new Uint8Array([1, 4, 9]);
+var doubles = numbers.map(function(num) {
+  return num * 2;
+});
+// doubles is now Uint8Array [2, 8, 18]
+// numbers is still Uint8Array [1, 4, 9]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.map', 'TypedArray.prototype.map')}}{{Spec2('ES2015')}}原始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.map', 'TypedArray.prototype.map')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop("38")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("38")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/name/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/name/index.html new file mode 100644 index 0000000000..4de20db129 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/name/index.html @@ -0,0 +1,117 @@ +--- +title: TypedArray.name +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/name +tags: + - JavaScript + - Property + - TypedArray + - TypedArrays + - 构造函数 +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/name +--- +
{{JSRef}}
+ +

TypedArray.name ?属性是描述类型数组构造名的字符串值。

+ +
{{js_property_attributes(0,0,0)}}
+ +

语法

+ +
TypedArray.name;
+ +

描述

+ +

TypedArray ?对象中,每个元素所含的字节数都与其它元素不同,因此其字节数需要被描述。name 属性描述了数组所包含的数据类型。其命名的第一部分可以是Int(整型)、Uint(无符整型)或Float(浮点);?其第二部分是一个描述数组所包含位数的数字;最后一部分为对象属性Array(ClampedArray为特例)。更多信息参见{{jsxref("Uint8ClampedArray")}}。

+ +

?例子

+ +
Int8Array.name;         // "Int8Array"
+Uint8Array.name;        // "Uint8Array"
+Uint8ClampedArray.name; // "Uint8ClampedArray"
+Int16Array.name;        // "Int16Array"
+Uint16Array.name;       // "Uint16Array"
+Int32Array.name;        // "Int32Array"
+Uint32Array.name;       // "Uint32Array"
+Float32Array.name;      // "Float32Array"
+Float64Array.name;      // "Float64Array"
+ +

?规范

+ + + + + + + + + + + + + + + + + + + +
规范?状态?注释
{{SpecName('ES6', '#sec-properties-of-the-typedarray-constructors', 'TypedArray.name')}}{{Spec2('ES6')}}初始定义
{{SpecName('ESDraft', '#sec-properties-of-the-typedarray-constructors', 'TypedArray.name')}}{{Spec2('ESDraft')}} 
+ +

?浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
?特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari
?基础支持7.0{{ CompatGeckoDesktop("2") }}1011.65.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础支持4.0{{CompatVersionUnknown}}{{CompatGeckoMobile("2")}}1011.64.2
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/of/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/of/index.html new file mode 100644 index 0000000000..1aafb4c2c6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/of/index.html @@ -0,0 +1,138 @@ +--- +title: TypedArray.of() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/of +tags: + - Typed + - TypedArray + - TypedArray.fo() + - TypedArray.from() +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/of +--- +
{{JSRef}}
+ +

TypedArray.of() 方法创建一个具有可变数量参数的新类型数组 。此方法几乎与{{jsxref("Array.of()")}} 相同。

+ +

句法

+ +
TypedArray.of(element0[, element1[, ...[, elementN]]])
+
+where TypedArray is one of:
+
+Int8Array
+Uint8Array
+Uint8ClampedArray
+Int16Array
+Uint16Array
+Int32Array
+Uint32Array
+Float32Array
+Float64Array
+ +

参数

+ +
+
elementN
+
创建类型数组的元素。
+
+ +

Return value

+ +

一个新的 {{jsxref("TypedArray")}}  实例。

+ +

描述

+ +

{{jsxref("Array.of()")}} 和 TypedArray.of()之间的一些细微区别:

+ + + +

范例

+ +
Uint8Array.of(1);            // Uint8Array [ 1 ]
+Int8Array.of("1", "2", "3"); // Int8Array [ 1, 2, 3 ]
+Float32Array.of(1, 2, 3);    // Float32Array [ 1, 2, 3 ]
+Int16Array.of(undefined);    // IntArray [ 0 ]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-%typedarray%.of', '%TypedArray%.of')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-%typedarray%.of', '%TypedArray%.of')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(45.0)}}{{CompatGeckoDesktop("38")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("38")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

也可以看看

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/prototype/index.html new file mode 100644 index 0000000000..d756bbf7bf --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/prototype/index.html @@ -0,0 +1,171 @@ +--- +title: TypedArray.prototype +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray +--- +
{{JSRef}}
+ +

TypedArray.prototype属性表示{{jsxref("TypedArray")}}构造器的原型.

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

{{jsxref("TypedArray")}} 实例继承自 {{jsxref("TypedArray.prototype")}}. 你可以通过该原型对象为所有的类型化数组(typed array types)实例添加属性和方法.

+ +

关于继承的更多的信息请参见关于TypedArray 的描述.

+ +

属性

+ +
+
TypedArray.prototype.constructor
+
返回创建实例原型的构造函数.这是相应的typed array type的默认的构造函数.
+
{{jsxref("TypedArray.prototype.buffer")}} {{readonlyInline}}
+
返回被格式化数组引用的{{jsxref("ArrayBuffer")}}. 创建时已被固化,因此是只读的.
+
{{jsxref("TypedArray.prototype.byteLength")}} {{readonlyInline}}
+
返回从{{jsxref("ArrayBuffer")}}读取的字节长度. 创建时已被固化,因此是只读的.
+
{{jsxref("TypedArray.prototype.byteOffset")}} {{readonlyInline}}
+
返回从{{jsxref("ArrayBuffer")}}读取时的字节偏移量.创建时已被固化,因此是只读的.
+
{{jsxref("TypedArray.prototype.length")}} {{readonlyInline}}
+
返回在类型化数组中的元素的数量.创建时已被固化,因此是只读的.
+
+ +

methods

+ +
+
{{jsxref("TypedArray.prototype.copyWithin()")}}
+
浅拷贝数组的部分元素到同一数组的不同位置,且不改变数组的大小,返回该数组. 参见 {{jsxref("Array.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.prototype.entries()")}}
+
返回一个 Array Iterator 对象,该对象包含数组中每一个索引的键值对.参见 {{jsxref("Array.prototype.entries()")}}.
+
{{jsxref("TypedArray.prototype.every()")}}
+
测试数组的所有元素是否都通过了指定函数的测试. 参见{{jsxref("Array.prototype.every()")}}.
+
{{jsxref("TypedArray.prototype.fill()")}}
+
将一个数组中指定区间的所有元素的值, 都替换成或者说填充成为某个固定的值. 参见 {{jsxref("Array.prototype.fill()")}}.
+
{{jsxref("TypedArray.prototype.filter()")}}
+
使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组. 参见 {{jsxref("Array.prototype.filter()")}}.
+
{{jsxref("TypedArray.prototype.find()")}}
+
返回一个满足提供的函数的测试的元素,若是没有满足的元素则返回undefined . 参见 {{jsxref("Array.prototype.find()")}}.
+
{{jsxref("TypedArray.prototype.findIndex()")}}
+
查找数组中某指定元素的索引, 如果找不到指定的元素, 则返回 -1. 参见 {{jsxref("Array.prototype.findIndex()")}}.
+
{{jsxref("TypedArray.prototype.forEach()")}}
+
对数组的每个元素执行一次提供的函数(回调函数). 参见 {{jsxref("Array.prototype.forEach()")}}.
+
{{jsxref("TypedArray.prototype.includes()")}} {{experimental_inline}}
+
确定一个类型化数组是否包括了某个元素,包含就返回true,不包含就返回false.参见 {{jsxref("Array.prototype.includes()")}}.
+
{{jsxref("TypedArray.prototype.indexOf()")}}
+
返回数组中第一个等于指定值得元素的索引,如果找不到则返回-1. 参见 {{jsxref("Array.prototype.indexOf()")}}.
+
{{jsxref("TypedArray.prototype.join()")}}
+
将数组中的所有元素连接成一个字符串. 参见 {{jsxref("Array.prototype.join()")}}.
+
{{jsxref("TypedArray.prototype.keys()")}}
+
返回一个新的包含数组索引的数组迭代器. 参见 {{jsxref("Array.prototype.keys()")}}.
+
{{jsxref("TypedArray.prototype.lastIndexOf()")}}
+
返回数组中最后一个等于指定值得元素的索引,如果找不到则返回-1.参见 {{jsxref("Array.prototype.lastIndexOf()")}}.
+
{{jsxref("TypedArray.prototype.map()")}}
+
创建一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组.参见 {{jsxref("Array.prototype.map()")}}.
+
{{jsxref("TypedArray.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
+
以前的不标准版本的 {{jsxref("TypedArray.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.prototype.reduce()")}}
+
接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值. 参见{{jsxref("Array.prototype.reduce()")}}.
+
{{jsxref("TypedArray.prototype.reduceRight()")}}
+
接受一个函数作为累加器(accumulator),让每个值(从右到左,亦即从尾到头)缩减为一个值.(与 reduce() 的执行方向相反). 参见{{jsxref("Array.prototype.reduceRight()")}}.
+
{{jsxref("TypedArray.prototype.reverse()")}}
+
颠倒数组中元素的位置。第一个元素会成为最后一个,最后一个会成为第一个. 参见 {{jsxref("Array.prototype.reverse()")}}.
+
{{jsxref("TypedArray.prototype.set()")}}
+
读取一个指定数组中的元素保存到格式化数组中.
+
{{jsxref("TypedArray.prototype.slice()")}}
+
浅复制(shallow copy)数组的一部分到一个新的数组,并返回这个新数组. 参见 {{jsxref("Array.prototype.slice()")}}.
+
{{jsxref("TypedArray.prototype.some()")}}
+
数组中只要有一个元素满足提供的测试函数的测试就返回true,否则返回false. 参见 {{jsxref("Array.prototype.some()")}}.
+
{{jsxref("TypedArray.prototype.sort()")}}
+
对数组进行排序,并返回原数组(是改变原数组). 参见 {{jsxref("Array.prototype.sort()")}}.
+
{{jsxref("TypedArray.prototype.subarray()")}}
+
返回给定的起始和结束索引之间的元素组成的新的类型化数组.
+
{{jsxref("TypedArray.prototype.values()")}}
+
返回有数组中的元素组成的新的数组迭代对象. 参见 {{jsxref("Array.prototype.values()")}}.
+
{{jsxref("TypedArray.prototype.toLocaleString()")}}
+
返回一个将数组中的每个元素本地化后组成的字符串. 参见 {{jsxref("Array.prototype.toLocaleString()")}}.
+
{{jsxref("TypedArray.prototype.toString()")}}
+
返回一个由数组中的每个元素字符串化后组成的字符串. 参见 {{jsxref("Array.prototype.toString()")}}.
+
{{jsxref("TypedArray.prototype.@@iterator()", "TypedArray.prototype[@@iterator]()")}}
+
返回一个包含数组中每个元素的新的数组迭代对象.
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES6', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support7.0{{ CompatGeckoDesktop("2") }}1011.65.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile("2") }}1011.64.2
+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/reduce/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/reduce/index.html new file mode 100644 index 0000000000..fe10f859c0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/reduce/index.html @@ -0,0 +1,137 @@ +--- +title: TypedArray.prototype.reduce() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/reduce +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/reduce +--- +
{{JSRef}}
+ +

reduce() 方法接受一个函数作为参数,这个函数作为一个累加器,从左到右遍历整个类型数组,最后返回一个单一的值. 这个方法和{{jsxref("Array.prototype.reduce()")}}使用了同样的算法. TypedArray 是一个 类型数组.

+ +

语法

+ +
typedarray.reduce(callback[, initialValue])
+ +

参数

+ +
+
callback
+
对类型数组的每一个值应用的函数,它接受以下参数: +
+
previousValue
+
在上一次迭代中,调用callback的返回值, 或者是提供的 initialValue。.
+
currentValue
+
类型化数组中当前要处理的值。
+
index
+
类型化数组中要处理的当前元素的下标
+
array
+
reduce 在其上调用的类型化数组。
+
+
+
initialValue
+
可选。用作 callback 首次调用的第一个参数的对象。
+
+ +

返回值

+ +

由归约返回的结果。

+ +

描述

+ +

reduce方法对类型化数组中出现的每个元素执行callback函数,除了类型化数组的空隙。它接受四个参数:初始值(或者来自之前callback调用的值),当前元素的值,当前下标,以及被遍历的类型化数组。

+ +

第一次调用回调函数的时候, previousValuecurrentValue 可以是两个值之一。如果 initialValuereduce的调用中提供, previousValue 会等于initialValue 并且currentValue 会等于类型化数组的第一个值。 如果 initialValue 没有提供,则previousValue等于类型化数组的第一个值,currentValue会等于第二个值。

+ +

如果类型化数组为空并且没有提供 initialValue,会抛出 {{jsxref("Global_Objects/TypeError", "TypeError")}} 。如果类型化数组中只有一个元素(无论位置)并且没有提供initialValue ,或者如果提供了initialValue 但是类型化数组为空,会返回唯一的值,但不会调用 callback

+ +

示例

+ +

累加数组中的所有值

+ +
var total = new Uint8Array([0, 1, 2, 3]).reduce(function(a, b) {
+  return a + b;
+});
+// total == 6
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-%typedarray%.prototype.reduce', '%TypedArray%.prototype.reduce')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.reduce', '%TypedArray%.prototype.reduce')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("47")}}12{{CompatGeckoDesktop("37")}}{{CompatUnknown}}{{CompatOpera("32")}}{{CompatSafari("10")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("37")}}{{CompatUnknown}}{{CompatUnknown}}10
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/reduceright/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/reduceright/index.html new file mode 100644 index 0000000000..ce443c7174 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/reduceright/index.html @@ -0,0 +1,144 @@ +--- +title: TypedArray.prototype.reduceRight() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/reduceRight +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/reduceRight +--- +
{{JSRef}}
+ +

reduceRight()在累加器和类型化数组的每个元素上(从右到左)调用函数,使其归约为单一的值。这个方法的算法和 {{jsxref("Array.prototype.reduceRight()")}}相同。 TypedArray 是这里的类型化数组类型 之一。

+ +

语法

+ +
typedarray.reduceRight(callback[, initialValue])
+ +

参数

+ +
+
callback
+
对类型数组的每一个值应用的函数,它接受四个参数: +
+
previousValue
+
回调函数上一次调用所返回的值,或者是提供的 initialValue
+
currentValue
+
类型化数组中当前要处理的值。
+
index
+
类型化数组中要处理的当前元素的下标
+
array
+
reduceRight 在其上调用的类型化数组
+
+
+
initialValue
+
可选。用作 callback 首次调用的第一个参数的对象。
+
+ +

返回值

+ +

由归约返回的结果。

+ +

描述

+ +

reduceRight方法对类型化数组中出现的每个元素执行callback函数,除了类型化数组的空隙。它接受四个参数:初始值(或者来自之前callback调用的值),当前元素的值,当前下标,以及被遍历的类型化数组。

+ +

reduceRight回调函数的调用是这样:

+ +
typedarray.reduceRight(function(previousValue, currentValue, index, typedarray) {
+  // ...
+});
+
+ +

第一次调用回调函数的时候, previousValuecurrentValue 可以是两个值之一。如果 initialValuereduce的调用中提供, previousValue 会等于initialValue 并且currentValue 会等于类型化数组的最后一个值。 如果 initialValue 没有提供,则previousValue等于类型化数组的最后一个值,currentValue会等于倒数第二个值。

+ +

如果类型化数组为空并且没有提供 initialValue,会抛出 {{jsxref("Global_Objects/TypeError", "TypeError")}} 。如果类型化数组中只有一个元素(无论位置)并且没有提供initialValue ,或者如果提供了initialValue 但是类型化数组为空,会返回唯一的值,但不会调用 callback

+ +

示例

+ +

累加数组中的所有值

+ +
var total = new Uint8Array([0, 1, 2, 3]).reduceRight(function(a, b) {
+  return a + b;
+});
+// total == 6
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-%typedarray%.prototype.reduceRight', '%TypedArray%.prototype.reduceRight')}}{{Spec2('ES6')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.reduceRight', '%TypedArray%.prototype.reduceRight')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("45")}}12{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatOpera("32")}}{{CompatSafari("10")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("37")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/reverse/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/reverse/index.html new file mode 100644 index 0000000000..b923d247d6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/reverse/index.html @@ -0,0 +1,106 @@ +--- +title: TypedArray.prototype.reverse() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/reverse +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/reverse +--- +
{{JSRef}}
+ +

reverse()方法原地翻转类型化数组。类型化数组的第一个元素变为最后一个,最后一个变为第一个。这个方法的算法和{{jsxref("Array.prototype.reverse()")}}相同。 TypedArray 是这里的 类型化数组类型 之一。

+ +

语法

+ +
typedarray.reverse();
+ +

返回值

+ +

翻转的数组。

+ +

示例

+ +
var uint8 = new Uint8Array([1, 2, 3]);
+uint8.reverse();
+
+console.log(uint8); // Uint8Array [3, 2, 1]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.reverse', 'TypedArray.prototype.reverse')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.reverse', 'TypedArray.prototype.reverse')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("45")}}12{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatOpera("32")}}{{CompatSafari("10")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoDesktop("37")}}{{CompatNo}}{{CompatNo}}10
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/set/index.html new file mode 100644 index 0000000000..3ba2095fbf --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/set/index.html @@ -0,0 +1,131 @@ +--- +title: TypedArray.prototype.set() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/set +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/set +--- +
{{JSRef}}
+ +

 set() 方法用于从指定数组中读取值,并将其存储在类型化数组中。

+ +

语法

+ +
typedarray.set(array[, offset])
+typedarray.set(typedarray[, offset])
+ +

参数

+ +
+
array
+
拷贝数据的源数组,源数组的所有值都会被复制到目标数组中,除非源数组的长度加上偏移量超过目标数组的长度,而在这种情况下会抛出异常。
+
参数array是源数组,指定从哪里拷贝值。源数组中的所有值都会被拷贝到目标数组中去。如果源数组的长度加上偏移值offset的结果超过目标数组的长度,则会抛出异常错误。
+
typedarray
+
如果源数组是一个类型化数组(typed array),则源数组和目标数组可以共享同一个底层的{{jsxref("ArrayBuffer")}};JavaScript 引擎会智能地将 buffer 的指定区段拷贝到目标区段中去。
+
offset {{ optional_inline() }}
+
偏移量参数 offset 指定从什么地方开始使用源数组 array 的值进行写入操作。如果忽略该参数,则默认为0(也就是说,从目标数组的下标为0处开始,使用源数组 array 的值覆盖重写)。
+
+ +

异常

+ +
+
{{jsxref("RangeError")}}
+
如果指定的偏移量超出了类型化数组的范围,则该异常会被抛出。
+
+ +

示例

+ +

使用 set()

+ +
var buffer = new ArrayBuffer(8);
+var uint8 = new Uint8Array(buffer);
+
+uint8.set([1,2,3], 3);
+
+console.log(uint8); // Uint8Array [ 0, 0, 0, 1, 2, 3, 0, 0 ]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
文档状态说明
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}ECMAScript 6中已废弃。
{{SpecName('ES6', '#sec-%typedarray%.prototype.set-array-offset', 'TypedArray.prototype.set')}}{{Spec2('ES6')}}在ECMA标准中初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.set-array-offset', 'TypedArray.prototype.set')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
浏览器ChromeFirefox (Gecko)Internet ExplorerOperaSafari
最低版本7.0{{CompatGeckoDesktop("2")}}1011.65.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
浏览器AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
最低版本4.0{{CompatVersionUnknown}}{{CompatGeckoMobile("2")}}1011.64.2
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/slice/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/slice/index.html new file mode 100644 index 0000000000..547cc36a8c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/slice/index.html @@ -0,0 +1,104 @@ +--- +title: TypedArray.prototype.slice() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/slice +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/slice +--- +
{{JSRef}}
+ +

slice()方法将一个typed array的一部分浅拷贝到一个新的typed array对象中并返回。此方法采用与 {{jsxref("Array.prototype.slice()")}}相同的算法。TypedArray指 typed array types中的一员 .

+ +
{{EmbedInteractiveExample("pages/js/typedarray-slice.html")}}
+ + + +

语法

+ +
typedarray.slice([begin[, end]])
+ +

参数

+ +
+
begin {{optional_inline}}
+
从0开始的索引位置。
+
可以使用负值索引, 表示从数组末尾往前的偏移量。slice(-2) 表示提取数组中的末尾两个元素.
+
如果没有设定起始位置,则将从开始位置开始截取。
+
end {{optional_inline}}
+
从0开始到尾元素前的索引值。 slice 取出的元素到此位置之前,不包含该位置。
+
例, slice(1,4) 表示读取第2个元素到第4个元素(元素索引:1, 2, 3)。
+
可以使用负值索引, 表示从数组末尾往前的偏移量。 slice(2,-1) 表示取出数组中的第3个到倒数第2个元素。
+
如果没有设定结束位置,则将从开始位置截取到序列尾部。(默认值为typedarray.length).
+
+ +

返回值

+ +

包含取出元素的新 typed array。

+ +

描述

+ +

slice方法并不会改变原数组的内容,它只是返回从原数组中取出的元素的浅复制集合。

+ +

如果一个新元素被添加到它们任何一个数组中去,另外一个数组不会受到影响。

+ +

示例

+ +

返回已存在类型数组的一部分片段

+ +
const uint8 = new Uint8Array([1,2,3]);
+uint8.slice(1);   // Uint8Array [ 2, 3 ]
+uint8.slice(2);   // Uint8Array [ 3 ]
+uint8.slice(-2);  // Uint8Array [ 2, 3 ]
+uint8.slice(0,1); // Uint8Array [ 1 ]
+
+ +

Polyfill

+ +

由于没有叫做TypedArray 的全局对象,必须在“按需”的基础上实现 Polyfill。

+ +
if (!Uint8Array.prototype.slice) {
+  Object.defineProperty(Uint8Array.prototype, 'slice', {
+    value: function (begin, end)
+     {
+        return new Uint8Array(Array.prototype.slice.call(this, begin, end));
+     }
+  });
+}
+ +

这不是一个完整的 polyfill,因为它返回的是一个Array的实例而不是Uint8Array,所以它没有TypedArrays应有的一些属性。

+ +

如果你要在不支持 Object.defineProperty 的老旧JavaScript引擎上支持这个特性,最好不要去实现 Array.prototype 中那些方法的 polyfill ,因为你没法让它们不可枚举。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.slice', '%TypedArray%.prototype.slice')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.slice', '%TypedArray%.prototype.slice')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.TypedArray.slice")}}

+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/some/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/some/index.html new file mode 100644 index 0000000000..2da4a21a65 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/some/index.html @@ -0,0 +1,121 @@ +--- +title: TypedArray.prototype.some() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/some +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/some +--- +
{{JSRef}}
+ +

这个 some() 方法检测 TypedArray 的一些元素是否通过所提供函数的测试. 这个方法和 {{jsxref("Array.prototype.some()")}} 相同. TypedArraytyped array types 之一.

+ +
{{EmbedInteractiveExample("pages/js/typedarray-some.html")}}
+ +
 
+ + + +

语法

+ +
typedarray.some(callback[, thisArg])
+ +

参数

+ +
+
callback
+
一个测试每个元素的函数,有3个参数: +
+
currentValue
+
在typed array中,正在被测试的元素.
+
index
+
在typed array中,正在被测试元素的索引.
+
array
+
正在被调用的 typed array 本身.
+
+
+
thisArg
+
可选的. callback  回调函数的 this 值 .
+
+ +

返回值

+ +

true 如果 callback 函数以任一数组元素为参数调用时,返回 {{Glossary("truthy")}}; 否则, false.

+ +

描述

+ +

对于 typed array 中的每个元素,some方法执行一次 callback,直到找到一个callback 返回 true 的元素. 如果一个元素被找到, some 立即返回 true. 否则, some 返回 false.

+ +

callback 期望3个参数: 元素的值, 元素的索引, 和被遍历的数组对象.

+ +

如果 some 提供 thisArg, 那么thisArg会作为 callback 调用时的this值. 否则, callback 调用时的 thisundefined.  callback 最终可观测的this 是根据  确定函数this的通常规则 所确定的.

+ +

some 被调用不会改变 typed array .

+ +

示例

+ +

Testing size of all typed array elements

+ +

以下示例测试typed array中的所有元素都大于10.

+ +
function isBiggerThan10(element, index, array) {
+  return element > 10;
+}
+new Uint8Array([2, 5, 8, 1, 4]).some(isBiggerThan10); // false
+new Uint8Array([12, 5, 8, 1, 4]).some(isBiggerThan10); // true
+
+ +

Testing typed array elements using arrow functions

+ +

Arrow functions 提供更段的语法做相同的测试.

+ +
new Uint8Array([2, 5, 8, 1, 4]).some(elem => elem > 10); // false
+new Uint8Array([12, 5, 8, 1, 4]).some(elem => elem > 10); // true
+ +

Polyfill

+ +

由于没有名为 TypedArray 的全局对象, 必须在“as needed”的基础上进行填充.

+ +
// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.some
+if (!Uint8Array.prototype.some) {
+  Object.defineProperty(Uint8Array.prototype, 'some', {
+    value: Array.prototype.some
+  });
+}
+
+ +

假如你需要支持的过时JavaScript引擎不支持Object.defineProperty,最好不要使用Array.prototype方法填充,因为你不能让它们不可枚举.

+ +

标准

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.some', 'TypedArray.prototype.some')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.some', 'TypedArray.prototype.some')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.builtins.TypedArray.some")}}

+
+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/sort/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/sort/index.html new file mode 100644 index 0000000000..1b0615c342 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/sort/index.html @@ -0,0 +1,126 @@ +--- +title: TypedArray.prototype.sort() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/sort +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/sort +--- +
{{JSRef}}
+ +

sort()方法原地排序类型化数组的元素,并且返回类型化数组。这个方法的算法和{{jsxref("Array.prototype.sort()")}}相同。 TypedArray 是这里的 类型化数组类型 之一。

+ +

语法

+ +
typedarray.sort([compareFunction])
+ +

参数

+ +
+
compareFunction {{optional_inline}}
+
指定定义排序顺序的函数
+
+ +

返回值

+ +

排序后的类型化数组。

+ +

示例

+ +

更多示例请参考 {{jsxref("Array.prototype.sort()")}} 方法。

+ +
var numbers = new Uint8Array([40, 1, 5, 200]);
+numbers.sort();
+// Uint8Array [ 1, 5, 40, 200 ]
+// 在这里,按数值排序数值时,
+// 不需要比较函数。
+
+var numbers = [40, 1, 5, 200];
+numbers.sort();
+// 将元素作为字符串来排序。
+// [1, 200, 40, 5]
+
+function compareNumbers(a, b) {
+  return a - b;
+}
+
+numbers.sort(compareNumbers);
+// [ 1, 5, 40, 200 ]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.sort', 'TypedArray.prototype.sort')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.sort', 'TypedArray.prototype.sort')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop(46)}}{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile(46)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/subarray/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/subarray/index.html new file mode 100644 index 0000000000..a15c160816 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/subarray/index.html @@ -0,0 +1,104 @@ +--- +title: TypedArray.prototype.subarray() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/subarray +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/subarray +--- +
{{JSRef}}
+ +
subarray() 返回一个新的、基于相同 {{jsxref("ArrayBuffer")}}、元素类型也相同的的 TypedArray。开始的索引将会被包括,而结束的索引将不会被包括。TypedArray 是指 typed array types 的其中之一。
+ +

 

+ +
{{EmbedInteractiveExample("pages/js/typedarray-subarray.html")}}
+ +

 

+ + + +

用法

+ +
typedarray.subarray([begin [,end]])
+
+ +

参数

+ +
+
begin {{optional_inline}}
+
元素开始的索引,开始索引的元素将会被包括。若该值没有传入,将会返回一个拥有全部元素的数组。
+
end {{optional_inline}}
+
元素结束的索引,结束索引的元素将不会被包括。若该值没有传入,从 begin 所指定的那一个元素到数组末尾的所有元素都将会被包含进新数组中。
+
+ +

返回值

+ +

一个新的 {{jsxref("TypedArray")}} 对象。

+ +

说明

+ + + +

需要注意的是,使用该方法返回的新数组还是建立在原有的 Buffer 之上的,所以,改动数组的内容将会影响到原数组,反之亦然。

+ +

 

+ +

Examples

+ +

 

+ +

Using the subarray method

+ +
var buffer = new ArrayBuffer(8);
+var uint8 = new Uint8Array(buffer);
+uint8.set([1,2,3]);
+
+console.log(uint8); // Uint8Array [ 1, 2, 3, 0, 0, 0, 0, 0 ]
+
+var sub = uint8.subarray(0,4);
+
+console.log(sub);   // Uint8Array [ 1, 2, 3, 0 ]
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-%typedarray%.prototype.subarray', 'TypedArray.prototype.subarray')}}{{Spec2('ES6')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.subarray', 'TypedArray.prototype.subarray')}}{{Spec2('ESDraft')}} 
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.TypedArray.subarray")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/tolocalestring/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/tolocalestring/index.html new file mode 100644 index 0000000000..c99fa0b350 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/tolocalestring/index.html @@ -0,0 +1,78 @@ +--- +title: TypedArray.prototype.toLocaleString() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/toLocaleString +tags: + - ECMAScript 2015 + - JavaScript + - TypedArray +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/toLocaleString +--- +
{{JSRef}}
+ +

toLocaleString()方法返回一个字符串,表明该类型化数组的元素。这些元素被转化为字符串并由一个区域设置指定的分隔符(例如逗号 “,”)分隔。这个方法与{{jsxref("Array.prototype.toLocaleString()")}}拥有相同的算法。同时,由于类型化数组的元素都是数,将每个元素转化为字符串的算法与{{jsxref("Number.prototype.toLocaleString()")}}是相同的。(类型化数组)的是typed array types中的其中一个。

+ +

语法

+ +
typedarray.toLocaleString([locales [, options]]);
+ +

参数

+ +
{{page('/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat', 'Parameters')}}
+ +

返回值

+ +

一个字符串,表明该类型化数组内的元素。

+ +

例子

+ +

使用toLocaleString

+ +
var uint = new Uint32Array([2000, 500, 8123, 12, 4212]);
+
+uint.toLocaleString();
+// 如果在de-DE区域设置下运行
+// "2.000,500,8.123,12,4.212"
+
+uint.toLocaleString('en-US');
+// "2,000,500,8,123,12,4,212"
+
+uint.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' });
+// "¥2,000,¥500,¥8,123,¥12,¥4,212"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES2015', '#sec-%typedarray%.prototype.tolocalestring', 'TypedArray.prototype.toLocaleString')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.tolocalestring', 'TypedArray.prototype.toLocaleString')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.TypedArray.toLocaleString")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/tostring/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/tostring/index.html new file mode 100644 index 0000000000..5da94eb0e4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/tostring/index.html @@ -0,0 +1,114 @@ +--- +title: TypedArray.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/toString +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/toString +--- +
{{JSRef}}
+ +

toString()方法返回一个表示指定数组及其元素的字符串。这个方法的算法和{{jsxref("Array.prototype.toString()")}}一样。TypedArray 在这是typed array types 之一。

+ +

语法

+ +
typedarray.toString()
+ +

返回值

+ +

一个字符串,表示类型数组(typed array)的元素。

+ +

描述

+ +

 {{jsxref("TypedArray")}} 对象重写了{{jsxref("Object")}}的 toString方法。对 TypedArray 对象来说,toString 方法联结了数组,并返回一个字符串,它包含由逗号分隔的数组元素。例如,下面的代码创建了一个类型数组,使用toString 将数组转化为字符串。

+ +
var numbers = new Uint8Array([2, 5, 8, 1, 4])
+numbers.toString(); // "2,5,8,1,4"
+
+ +

当一个类型数组表示为文本值,或者当一个数组被用于字符串连接,则JavaScript 将自动调用 toString 方法。

+ +

兼容性

+ +

如果浏览器还不支持TypedArray.prototype.toString() 方法,JavaScript 将调用{{jsxref("Object")}}的 toString 方法:

+ +
var numbers = new Uint8Array([2, 5, 8, 1, 4])
+numbers.toString(); // "[object Uint8Array]"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-%typedarray%.prototype.tostring', 'TypedArray.prototype.toString')}}{{Spec2('ES6')}}初始定义
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.tostring', 'Array.prototype.toString')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop(51)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile(51)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/values/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/values/index.html new file mode 100644 index 0000000000..16d89f9aee --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typedarray/values/index.html @@ -0,0 +1,126 @@ +--- +title: TypedArray.prototype.values() +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/values +translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray/values +--- +
{{JSRef}}
+ +

values()返回新的 Array Iterator 对象,包含数组中每个下标处的值。

+ +

语法

+ +
arr.values()
+ +

返回值

+ +

新的Array Iterator对象。

+ +

示例

+ +

使用for...of 循环的迭代

+ +
var arr = new Uint8Array([10, 20, 30, 40, 50]);
+var eArray = arr.values();
+// 你的浏览器必须支持 for..of 循环
+// 以及 for 循环中的 let 区域变量
+for (let n of eArray) {
+  console.log(n);
+}
+
+ +

备选迭代

+ +
var arr = new Uint8Array([10, 20, 30, 40, 50]);
+var eArr = arr.values();
+console.log(eArr.next().value); // 10
+console.log(eArr.next().value); // 20
+console.log(eArr.next().value); // 30
+console.log(eArr.next().value); // 40
+console.log(eArr.next().value); // 50
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-%typedarray%.prototype.values', '%TypedArray%.prototype.values()')}}{{Spec2('ES2015')}}初始定义。
{{SpecName('ESDraft', '#sec-%typedarray%.prototype.values', '%TypedArray%.prototype.values()')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown }}12{{CompatGeckoDesktop(37)}}{{CompatNo}}{{CompatOpera("26")}}{{CompatSafari("10")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{ CompatVersionUnknown }}{{CompatGeckoMobile(37)}}{{CompatNo}}{{CompatNo}}10
+
+ +

另见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typeerror/index.html b/files/zh-cn/web/javascript/reference/global_objects/typeerror/index.html new file mode 100644 index 0000000000..e8710ef901 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typeerror/index.html @@ -0,0 +1,133 @@ +--- +title: TypeError +slug: Web/JavaScript/Reference/Global_Objects/TypeError +tags: + - Error + - JavaScript + - Object + - Reference + - Référence(2) + - TypeError + - 参考 + - 类型错误 +translation_of: Web/JavaScript/Reference/Global_Objects/TypeError +--- +
{{JSRef}}
+ +

TypeError(类型错误) 对象用来表示值的类型非预期类型时发生的错误。

+ +

语法

+ +
new TypeError([message[, fileName[, lineNumber]]])
+ +

参数

+ +
+
message 消息
+
可选. 描述此错误
+
fileName 文件名 {{non-standard_inline}}
+
可选. 引起该异常的代码所在的文件的名字。
+
lineNumber 行号 {{non-standard_inline}}
+
可选. 引起该异常的代码的行号。
+
+ +

描述

+ +

当传入函数的操作数参数的类型并非操作符或函数所预期的类型时,将抛出一个 TypeError 类型错误。

+ +

属性

+ +
+
{{jsxref("TypeError.prototype")}}
+
允许为一个 TypeError 类型错误附加属性。
+
+ +

方法

+ +

全局 TypeError 不包含任何方法,不过,它将从原型链中继承一些方法。

+ +

TypeError 类型错误实例

+ +

属性

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypeError/prototype', '属性')}}
+ +

方法

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypeError/prototype', '方法')}}
+ +

示例

+ +

示例: 捕获类型错误

+ +
try {
+  null.f();
+} catch (e) {
+  console.log(e instanceof TypeError); // true
+  console.log(e.message);              // "null has no properties"
+  console.log(e.name);                 // "TypeError"
+  console.log(e.fileName);             // "Scratchpad/1"
+  console.log(e.lineNumber);           // 2
+  console.log(e.columnNumber);         // 2
+  console.log(e.stack);                // "@Scratchpad/2:2:3\n"
+}
+
+ +

示例: 创建一个类型错误

+ +
try {
+  throw new TypeError('Hello', "someFile.js", 10);
+} catch (e) {
+  console.log(e instanceof TypeError); // true
+  console.log(e.message);              // "Hello"
+  console.log(e.name);                 // "TypeError"
+  console.log(e.fileName);             // "someFile.js"
+  console.log(e.lineNumber);           // 10
+  console.log(e.columnNumber);         // 0
+  console.log(e.stack);                // "@Scratchpad/2:2:9\n"
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES3', '#sec-15.11.6.5', 'TypeError')}}{{Spec2('ES3')}}初始定义。
{{SpecName('ES5.1', '#sec-15.11.6.5', 'TypeError')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-native-error-types-used-in-this-standard-typeerror', 'TypeError')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ + + +
{{Compat("javascript.builtins.TypeError")}}
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/typeerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/typeerror/prototype/index.html new file mode 100644 index 0000000000..058c791b71 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/typeerror/prototype/index.html @@ -0,0 +1,93 @@ +--- +title: TypeError.prototype +slug: Web/JavaScript/Reference/Global_Objects/TypeError/prototype +tags: + - Error + - JavaScript + - TypeError + - 原型 + - 错误 +translation_of: Web/JavaScript/Reference/Global_Objects/TypeError +--- +
{{JSRef}}
+ +

TypeError.prototype 属性表示 {{jsxref("TypeError")}}构造函数的原型。

+ +

 

+ +

描述

+ +

所有{{jsxref("TypeError")}}实例都继承自TypeError.prototype。您可以使用原型向所有实例添加属性或方法

+ +

 

+ +

属性

+ +
+
TypeError.prototype.constructor
+
声明创建实例原型 (prototype) 的方法。
+
{{jsxref("Error.prototype.message", "TypeError.prototype.message")}}
+
错误信息。虽然 ECMA-262 规范指出 {{jsxref("TypeError")}} 应该实现其自身的 message 属性,但是在 SpiderMonkey 中,该属性继承自 {{jsxref("Error.prototype.message")}}。
+
{{jsxref("Error.prototype.name", "TypeError.prototype.name")}}
+
错误名称。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.fileName", "TypeError.prototype.fileName")}}
+
引起该错误的代码所在文件的路径。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.lineNumber", "TypeError.prototype.lineNumber")}}
+
引起错误的代码所在行的行号。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.columnNumber", "TypeError.prototype.columnNumber")}}
+
引起错误的代码所在列的列号。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.stack", "TypeError.prototype.stack")}}
+
堆栈跟踪记录。 继承自 {{jsxref("Error")}}。
+
+ +

方法

+ +

尽管 {{jsxref("TypeError")}} 不包含任何自己的方法, 但{{jsxref("TypeError")}}的实例通过原型链继承了一些方法。

+ +

 

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}} 定义为 NativeError.prototype.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}} 定义为 NativeError.prototype.
{{SpecName('ES3', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES3')}} 初始定义
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.TypeError")}}

+ +
 
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/uint16array/index.html b/files/zh-cn/web/javascript/reference/global_objects/uint16array/index.html new file mode 100644 index 0000000000..6d7fadd8e9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/uint16array/index.html @@ -0,0 +1,160 @@ +--- +title: Uint16Array +slug: Web/JavaScript/Reference/Global_Objects/Uint16Array +translation_of: Web/JavaScript/Reference/Global_Objects/Uint16Array +--- +
{{JSRef}}
+ +

该 Uint16Array 类型数组表示16位无符号整数,按平台字节顺序排列。如果需要控制字节顺序,请使用 DataView 代替。内容被初始化为0。建立后,就可以使用对象的方法或使用标准数组索引语法(即使用括号表示法)引用数组中的元素。

+ +

构造函数

+ +
+
Uint16Array()
+
创建一个新的 Uint16Array 对象。
+
+ +

静态属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "Uint16Array.BYTES_PER_ELEMENT")}}
+
返回元素大小的数值。在 Uint16Array 情况下为 2
+
{{jsxref("TypedArray.name", "Uint16Array.name")}}
+
返回构造函数名称的字符串值。 在 Uint16Array 情况下,类型为: "Uint16Array"。
+
+ +

静态方法

+ +
+
{{jsxref("TypedArray.from", "Uint16Array.from()")}}
+
从类数组或可迭代对象创建一个新的 Uint16Array 。可参阅 {{jsxref("Array.from()")}}。
+
{{jsxref("TypedArray.of", "Uint16Array.of()")}}
+
创建一个新的具有可变参数数目的 Uint16Array 。可参阅 {{jsxref("Array.of()")}}。
+
+ +

实例属性

+ +
+
{{jsxref("TypedArray.prototype.buffer", "Uint16Array.prototype.buffer")}}
+
返回 Uint16Array 在构造时固定引用的 {{jsxref("ArrayBuffer")}} 。因此是 只读的
+
{{jsxref("TypedArray.prototype.byteLength", "Uint16Array.prototype.byteLength")}}
+
返回 Uint16Array 从 {{jsxref("ArrayBuffer")}}开始的长度(以字节为单位)。在构建时固定,因此是 只读的 。
+
{{jsxref("TypedArray.prototype.byteOffset", "Uint16Array.prototype.byteOffset")}}
+
返回 Uint16Array 从 {{jsxref("ArrayBuffer")}}开始的偏移量(以字节为单位)。在构建时固定,因此是 只读的 。
+
{{jsxref("TypedArray.prototype.length", "Uint16Array.prototype.length")}}
+
返回 Uint16Array 中包含的元素数量。在构建时固定,因此是 只读的 。
+
+ +

实例方法

+ +
+
{{jsxref("TypedArray.copyWithin", "Uint16Array.prototype.copyWithin()")}}
+
复制数组中的一序列数组元素。 可参阅 {{jsxref("Array.prototype.copyWithin()")}}。
+
{{jsxref("TypedArray.entries", "Uint16Array.prototype.entries()")}}
+
返回一个新的 Array Iterator 对象,该对象包含数组中的每个索引的键/值对。可参阅 {{jsxref("Array.prototype.entries()")}}。
+
{{jsxref("TypedArray.every", "Uint16Array.prototype.every()")}}
+
测试数组中的所有元素是否通过函数提供的测试。 可参阅 {{jsxref("Array.prototype.every()")}}。
+
{{jsxref("TypedArray.fill", "Uint16Array.prototype.fill()")}}
+
使用静态值填充从开始索引到结束索引的数组的所有元素。 可参阅 {{jsxref("Array.prototype.fill()")}}。
+
{{jsxref("TypedArray.filter", "Uint16Array.prototype.filter()")}}
+
根据所提供的过滤函数,将所有返回true的所有元素创建一个新的数组。可参阅 {{jsxref("Array.prototype.filter()")}}。
+
{{jsxref("TypedArray.find", "Uint16Array.prototype.find()")}}
+
返回数组中满足所提供的测试函数的值,没有则返回 undefined 。 可参阅 {{jsxref("Array.prototype.find()")}}。
+
{{jsxref("TypedArray.findIndex", "Uint16Array.prototype.findIndex()")}}
+
返回数组中满足所提供的测试函数的索引,没有则返回 -1。 可参阅 {{jsxref("Array.prototype.findIndex()")}}。
+
{{jsxref("TypedArray.forEach", "Uint16Array.prototype.forEach()")}}
+
为数组中的每个元素调用一个函数。 可参阅 {{jsxref("Array.prototype.forEach()")}}。
+
{{jsxref("TypedArray.includes", "Uint16Array.prototype.includes()")}}
+
判断数组中是否包含某个元素,有则返回 true ,无则返回 false 。 可参阅 {{jsxref("Array.prototype.includes()")}}。
+
{{jsxref("TypedArray.indexOf", "Uint16Array.prototype.indexOf()")}}
+
返回数组中等于指定的值的元素第一个(最小)索引,没有则返回 -1。 可参阅 {{jsxref("Array.prototype.indexOf()")}}。
+
{{jsxref("TypedArray.join", "Uint16Array.prototype.join()")}}
+
将数组中的所有元素连接成字符串。可参阅 {{jsxref("Array.prototype.join()")}}。
+
{{jsxref("TypedArray.keys", "Uint16Array.prototype.keys()")}}
+
f返回一个新的 Array Iterator ,其包含数组中每个索引的键。 可参阅 {{jsxref("Array.prototype.keys()")}}。
+
{{jsxref("TypedArray.lastIndexOf", "Uint16Array.prototype.lastIndexOf()")}}
+
返回数组中最后一个(最大的)与指定值相等的元素的索引,没有则返回 -1。可参阅 {{jsxref("Array.prototype.lastIndexOf()")}}。
+
{{jsxref("TypedArray.map", "Uint16Array.prototype.map()")}}
+
返回一个根据所提供的函数对每个元素处理后的新数组。可参阅 {{jsxref("Array.prototype.map()")}}。
+
{{jsxref("TypedArray.reduce", "Uint16Array.prototype.reduce()")}}
+
根据所提供的函数对累加器和数组的每一个值(从左到右)进行处理,并返回最后调用函数的值。可参阅 {{jsxref("Array.prototype.reduce()")}}。
+
{{jsxref("TypedArray.reduceRight", "Uint16Array.prototype.reduceRight()")}}
+
根据所提供的函数对累加器和数组的每一个值(从右到左)进行处理,并返回最后调用函数的值。 可参阅 {{jsxref("Array.prototype.reduceRight()")}}。
+
{{jsxref("TypedArray.reverse", "Uint16Array.prototype.reverse()")}}
+
颠倒数组的顺序,使第一个元素成为最后一个,最后一个元素成为第一个。 可参阅 {{jsxref("Array.prototype.reverse()")}}。
+
{{jsxref("TypedArray.set", "Uint16Array.prototype.set()")}}
+
在类型化数组中存储多个值,从指定数组中读取输入值。
+
{{jsxref("TypedArray.slice", "Uint16Array.prototype.slice()")}}
+
截取数组中的一部分并作为新数组返回。 可参阅 {{jsxref("Array.prototype.slice()")}}。
+
{{jsxref("TypedArray.some", "Uint16Array.prototype.some()")}}
+
判读数组中是否至少有一个元素满足所提供的测试函数,有则返回 true。 可参阅 {{jsxref("Array.prototype.some()")}}。
+
{{jsxref("TypedArray.sort", "Uint16Array.prototype.sort()")}}
+
对数组中的元素进行排序并返回排序后的数组。 可参阅 {{jsxref("Array.prototype.sort()")}}。
+
{{jsxref("TypedArray.subarray", "Uint16Array.prototype.subarray()")}}
+
从给定的开始与结束元素索引中返回一个新的 Uint16Array 。
+
{{jsxref("TypedArray.values", "Uint16Array.prototype.values()")}}
+
返回一个新的 Array Iterator 对象,该对象包含数组中的每个索引的值。 可参阅 {{jsxref("Array.prototype.values()")}}.
+
{{jsxref("TypedArray.toLocaleString", "Uint16Array.prototype.toLocaleString()")}}
+
返回表示数组及其元素的本地化字符串。 可参阅 {{jsxref("Array.prototype.toLocaleString()")}}。
+
{{jsxref("TypedArray.toString", "Uint16Array.prototype.toString()")}}
+
返回表示数组及其元素的字符串。可参阅 {{jsxref("Array.prototype.toString()")}}。
+
{{jsxref("TypedArray.@@iterator", "Uint16Array.prototype[@@iterator]()")}}
+
返回一个新的 Array Iterator 对象, 其包含数组中每个索引的值。
+
+ +

示例

+ +

Different ways to create a Uint16Array

+ +
// 长度
+var uint16 = new Uint16Array(2);
+uint16[0] = 42;
+console.log(uint16[0]); // 42
+console.log(uint16.length); // 2
+console.log(uint16.BYTES_PER_ELEMENT); // 2
+
+// 数组
+var arr = new Uint16Array([21,31]);
+console.log(arr[1]); // 31
+
+// 另一个类型数组
+var x = new Uint16Array([21, 31]);
+var y = new Uint16Array(x);
+console.log(y[0]); // 21
+
+// 一个 ArrayBuffer
+var buffer = new ArrayBuffer(8);
+var z = new Uint16Array(buffer, 0, 4);
+
+// 可迭代
+var iterable = function*(){ yield* [1,2,3]; }();
+var uint16 = new Uint16Array(iterable);
+// Uint16Array[1, 2, 3]
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#table-49', 'TypedArray constructors')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Uint16Array")}}

+ +

可参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/uint32array/index.html b/files/zh-cn/web/javascript/reference/global_objects/uint32array/index.html new file mode 100644 index 0000000000..1239590bdf --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/uint32array/index.html @@ -0,0 +1,176 @@ +--- +title: Uint32Array +slug: Web/JavaScript/Reference/Global_Objects/Uint32Array +translation_of: Web/JavaScript/Reference/Global_Objects/Uint32Array +--- +
{{JSRef("Global_Objects", "TypedArray", "Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array")}}
+ +
+ +

Uint32Array 表示一个由基于平台字节序的32位无符号字节组成的数组。如果需要对字节顺序进行控制(译者注:即 littleEndian 或 bigEndian),请使用 {{jsxref("DataView")}} 代替。数组中每个元素的初始值都是0。一旦创建,你可以用对象的方法引用数组里的元素,或者使用标准的数组索引语法(即,使用中括号)。

+ +

语法

+ +
new Uint32Array(); // new in ES2017
+new Uint32Array(length);
+new Uint32Array(typedArray);
+new Uint32Array(object);
+new Uint32Array(buffer [, byteOffset [, length]]);
+ +

更多的构造器语法和属性请参照 TypedArray

+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "Uint32Array.BYTES_PER_ELEMENT")}}
+
返回一个数值,代表Uint32Array中单个元素的字节大小。Uint32Array 返回 4
+
Uint32Array.length
+
固定值(static)属性,值为3。使用 {{jsxref("TypedArray.prototype.length", "Uint32Array.prototype.length")}} 获得数组的真实长度(元素个数)。
+
{{jsxref("TypedArray.name", "Uint32Array.name")}}
+
返回字符串类型的值,表示构造器的名字。Uint32Array 的返回值是: "Uint32Array"。
+
{{jsxref("TypedArray.prototype", "Uint32Array.prototype")}}
+
TypedArray 对象的原型链。
+
+ +

方法

+ +
+
{{jsxref("TypedArray.from", "Uint32Array.from()")}}
+
从类似数组或者可迭代对象创建一个新的 Uint32Array 。请参考 {{jsxref("Array.from()")}}.
+
{{jsxref("TypedArray.of", "Uint32Array.of()")}}
+
从可变长度的参数创建一个新的 Uint32Array 。请参考 {{jsxref("Array.of()")}}.
+
+ +

Uint32Array 原型

+ +

所有 Uint32Array 对象继承自 {{jsxref("TypedArray.prototype", "%TypedArray%.prototype")}}.

+ +

属性

+ +
+
Uint32Array.prototype.constructor
+
返回创建实例原型的函数。 默认返回 Uint32Array 的构造器。
+
{{jsxref("TypedArray.prototype.buffer", "Uint32Array.prototype.buffer")}} {{readonlyInline}}
+
返回 Uint32Array引用的 {{jsxref("ArrayBuffer")}}。 由于构造时已固定,所以是只读的
+
{{jsxref("TypedArray.prototype.byteLength", "Uint32Array.prototype.byteLength")}} {{readonlyInline}}
+
返回从其 {{jsxref("ArrayBuffer")}} 开始的 Uint32Array 字节长度。由于构造时已固定,所以是只读的
+
{{jsxref("TypedArray.prototype.byteOffset", "Uint32Array.prototype.byteOffset")}} {{readonlyInline}}
+
返回从其 {{jsxref("ArrayBuffer")}} 的偏移开始的 Uint32Array 字节长度。由于构造时已固定,所以是只读的
+
{{jsxref("TypedArray.prototype.length", "Uint32Array.prototype.length")}} {{readonlyInline}}
+
返回 Uint32Array  中元素的个数。由于构造时已固定,所以是只读的
+
+ +

方法

+ +
+
{{jsxref("TypedArray.copyWithin", "Uint32Array.prototype.copyWithin()")}}
+
拷贝(浅拷贝)数组的部分元素到本数组的不同位置(不改变数组的大小)。请参考 {{jsxref("Array.prototype.copyWithin()")}}。
+
{{jsxref("TypedArray.entries", "Uint32Array.prototype.entries()")}}
+
返回一个 Array Iterator 对象,该对象包含数组中每一对索引的键值对。请参考 {{jsxref("Array.prototype.entries()")}}。
+
{{jsxref("TypedArray.every", "Uint32Array.prototype.every()")}}
+
测试是否数组中的所有元素都通过给定的测试函数。请参考 {{jsxref("Array.prototype.every()")}}。
+
{{jsxref("TypedArray.fill", "Uint32Array.prototype.fill()")}}
+
使用静态值填充从起始下标到终止下标的数组元素。请参考 {{jsxref("Array.prototype.fill()")}}。
+
{{jsxref("TypedArray.filter", "Uint32Array.prototype.filter()")}}
+
创造一个新数组,含有原数组中可通过给定的过滤器函数的所有元素。请参考 {{jsxref("Array.prototype.filter()")}}。
+
{{jsxref("TypedArray.find", "Uint32Array.prototype.find()")}}
+
如果数组中的元素满足提供的测试函数,返回找到的值,如果没有找到则返回 undefined。请参考 {{jsxref("Array.prototype.find()")}}。
+
{{jsxref("TypedArray.findIndex", "Uint32Array.prototype.findIndex()")}}
+
如果数组中的元素满足提供的测试函数,返回找到的下标,如果没有找到则返回 -1。请参考 {{jsxref("Array.prototype.findIndex()")}}。
+
{{jsxref("TypedArray.forEach", "Uint32Array.prototype.forEach()")}}
+
对数组内的每个元素调用一个函数。请参考 {{jsxref("Array.prototype.forEach()")}}。
+
{{jsxref("TypedArray.includes", "Uint32Array.prototype.includes()")}}
+
判断该数组是否包含特定值,如果包含返回 true,否则返回false。请参考 {{jsxref("Array.prototype.includes()")}}。
+
{{jsxref("TypedArray.indexOf", "Uint32Array.prototype.indexOf()")}}
+
返回数组中等于特定值的第一个元素(下标最小)的下标,如果没有找到则返回 -1。请参考 {{jsxref("Array.prototype.indexOf()")}}。
+
{{jsxref("TypedArray.join", "Uint32Array.prototype.join()")}}
+
将数组内的元素拼接成一个字符串。请参考 {{jsxref("Array.prototype.join()")}}。
+
{{jsxref("TypedArray.keys", "Uint32Array.prototype.keys()")}}
+
返回一个 Array Iterator 对象,该对象包含数组中所有索引(key)。请参考 {{jsxref("Array.prototype.keys()")}}。
+
{{jsxref("TypedArray.lastIndexOf", "Uint32Array.prototype.lastIndexOf()")}}
+
返回数组中等于特定值的最后一个元素(下标最大)的下标,如果没有找到则返回 -1。请参考 {{jsxref("Array.prototype.lastIndexOf()")}}。
+
{{jsxref("TypedArray.map", "Uint32Array.prototype.map()")}}
+
用该数组的每个元素调用给定函数的结果创建新数组。请参考 {{jsxref("Array.prototype.map()")}}。
+
{{jsxref("TypedArray.reduce", "Uint32Array.prototype.reduce()")}}
+
对累加器和数组的每个值应用函数(从左到右),使其归约为单一的值。请参考 {{jsxref("Array.prototype.reduce()")}}。
+
{{jsxref("TypedArray.reduceRight", "Uint32Array.prototype.reduceRight()")}}
+
对累加器和数组的每个值应用函数(从右到左),使其归约为单一的值。请参考 {{jsxref("Array.prototype.reduceRight()")}}。
+
{{jsxref("TypedArray.reverse", "Uint32Array.prototype.reverse()")}}
+
翻转数组中的元素顺序——首尾颠倒。请参考 {{jsxref("Array.prototype.reverse()")}}。
+
{{jsxref("TypedArray.set", "Uint32Array.prototype.set()")}}
+
从一个给定的数组中读取多个数据并存储至 typed array。
+
{{jsxref("TypedArray.slice", "Uint32Array.prototype.slice()")}}
+
提取数组的某个部分并返回新的数组。请参考 {{jsxref("Array.prototype.slice()")}}。
+
{{jsxref("TypedArray.some", "Uint32Array.prototype.some()")}}
+
测试是否数组中有(至少一个)元素可通过给定的测试函数。请参考 {{jsxref("Array.prototype.some()")}}。
+
{{jsxref("TypedArray.sort", "Uint32Array.prototype.sort()")}}
+
就地排序数组中的元素,并返回该数组。请参考 {{jsxref("Array.prototype.sort()")}}。
+
{{jsxref("TypedArray.subarray", "Uint32Array.prototype.subarray()")}}
+
根据给定的起始和结束元素下标,返回一个新的 Uint32Array 子数组。
+
{{jsxref("TypedArray.values", "Uint32Array.prototype.values()")}}
+
返回新的 Array Iterator 对象,其含有数组中每个索引的值。请参考 {{jsxref("Array.prototype.values()")}}。
+
{{jsxref("TypedArray.toLocaleString", "Uint32Array.prototype.toLocaleString()")}}
+
返回表示数组及其元素的本地化字符串。请参考 {{jsxref("Array.prototype.toLocaleString()")}}。
+
{{jsxref("TypedArray.toString", "Uint32Array.prototype.toString()")}}
+
返回表示数组及其元素的字符串。请参考 {{jsxref("Array.prototype.toString()")}}。
+
{{jsxref("TypedArray.@@iterator", "Uint32Array.prototype[@@iterator]()")}}
+
返回新的 Array Iterator 对象,其含有数组中每个索引的值。
+
+ +

示例

+ +

用不同的方法创建 Uint32Array

+ +
// 给定长度
+var uint32 = new Uint32Array(2);
+uint32[0] = 42;
+console.log(uint32[0]); // 42
+console.log(uint32.length); // 2
+console.log(uint32.BYTES_PER_ELEMENT); // 4
+
+// 给定数组
+var arr = new Uint32Array([21, 31]);
+console.log(arr[1]); // 31
+
+// 给定 TypedArray
+var x = new Uint32Array([21, 31]);
+var y = new Uint32Array(x);
+console.log(y[0]); // 21
+
+// 给定 ArrayBuffer
+var buffer = new ArrayBuffer(16);
+var z = new Uint32Array(buffer, 0, 4);
+
+// 给定可迭代对象
+var iterable = function*(){ yield* [1, 2, 3]; }();
+var uint32 = new Uint32Array(iterable);
+// Uint32Array[1, 2, 3]
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#table-49', 'TypedArray constructors')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Uint32Array")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/uint8array/index.html b/files/zh-cn/web/javascript/reference/global_objects/uint8array/index.html new file mode 100644 index 0000000000..1619a2abb3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/uint8array/index.html @@ -0,0 +1,193 @@ +--- +title: Uint8Array +slug: Web/JavaScript/Reference/Global_Objects/Uint8Array +translation_of: Web/JavaScript/Reference/Global_Objects/Uint8Array +--- +
{{JSRef}}
+ +

Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。

+ +

语法格式

+ +
new Uint8Array(); // ES2017 最新语法
+new Uint8Array(length); // 创建初始化为0的,包含length个元素的无符号整型数组
+new Uint8Array(typedArray);
+new Uint8Array(object);
+new Uint8Array(buffer [, byteOffset [, length]]);
+ +

构造语法和参数的更多信息请参见 TypedArray.

+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "Uint8Array.BYTES_PER_ELEMENT")}}
+
返回数组中元素的字节数,Uint8Array中返回1字节。
+
Uint8Array.length
+
静态属性length一直为0。想获知其真实长度(元素个数),请参阅 {{jsxref("TypedArray.prototype.length", "Uint8Array.prototype.length")}}.
+
{{jsxref("TypedArray.name", "Uint8Array.name")}}
+
返回构造名的字符串,对Uint8Array类型而言返回 “Uint8Array”
+
{{jsxref("TypedArray.prototype", "Uint8Array.prototype")}}
+
TypedArray 对象的原型.
+
+ +

方法

+ +
+
{{jsxref("TypedArray.from", "Uint8Array.from()")}}
+
从一个数组或可迭代的对象创建一个新的Uint8Array数组,可参见{{jsxref("Array.from()")}}.
+
{{jsxref("TypedArray.of", "Uint8Array.of()")}}
+
通过一个可变数目的参数创建一个新的Uint8Array数组,可参见{{jsxref("Array.of()")}}.
+
+ +

Uint8Array 原型声明

+ +

所有的Uint8Array对象继承自 {{jsxref("TypedArray.prototype", "%TypedArray%.prototype")}}.

+ +

属性

+ +
+
Uint8Array.prototype.constructor
+
返回创建实例属性的函数,默认为 Uint8Array 构造器。
+
{{jsxref("TypedArray.prototype.buffer", "Uint8Array.prototype.buffer")}} {{readonlyInline}}
+
返回由 Uint8Array引用的 {{jsxref("ArrayBuffer")}} ,在构造时期固定,所以是只读的。
+
{{jsxref("TypedArray.prototype.byteLength", "Uint8Array.prototype.byteLength")}} {{readonlyInline}}
+
返回Uint8Array长度(字节数)。在构造时期固定,所以是 只读的
+
{{jsxref("TypedArray.prototype.byteOffset", "Uint8Array.prototype.byteOffset")}} {{readonlyInline}}
+
返回Uint8Array 距离其 {{jsxref("ArrayBuffer")}} 起始位置的偏移(字节数)。在构造时期固定,所以是 只读的
+
{{jsxref("TypedArray.prototype.length", "Uint8Array.prototype.length")}} {{readonlyInline}}
+
返回保存在 Uint8Array中的元素数量。 在构造时期固定,所以是 只读的
+
+ +

方法

+ +
+
{{jsxref("TypedArray.copyWithin", "Uint8Array.prototype.copyWithin()")}}
+
复制数组中的元素序列,请参见 {{jsxref("Array.prototype.copyWithin()")}}。
+
{{jsxref("TypedArray.entries", "Uint8Array.prototype.entries()")}}
+
返回新的Array Iterator 对象,含有数组中每个下标处的键值对。请参见{{jsxref("Array.prototype.entries()")}}.
+
{{jsxref("TypedArray.every", "Uint8Array.prototype.every()")}}
+
测试数组中所有元素是否都能通过由函数提供的测试。请参见 {{jsxref("Array.prototype.every()")}}。
+
{{jsxref("TypedArray.fill", "Uint8Array.prototype.fill()")}}
+
使用静态值填充从起始下标到终止下标的数组元素。请参见 {{jsxref("Array.prototype.fill()")}}。
+
{{jsxref("TypedArray.filter", "Uint8Array.prototype.filter()")}}
+
创建新的数组,含有数组中给定过滤器返回 true 的所有元素。请参见{{jsxref("Array.prototype.filter()")}}.
+
{{jsxref("TypedArray.find", "Uint8Array.prototype.find()")}}
+
如果数组中的元素满足提供的测试函数,返回找到的值,如果没有找到则返回 undefined。请参见 {{jsxref("Array.prototype.find()")}}。
+
{{jsxref("TypedArray.findIndex", "Uint8Array.prototype.findIndex()")}}
+
如果数组中的元素满足提供的测试函数,返回找到的下标,如果没有找到则返回 -1。请参见 {{jsxref("Array.prototype.findIndex()")}}.
+
{{jsxref("TypedArray.forEach", "Uint8Array.prototype.forEach()")}}
+
对数组的每个元素调用字符串 {{jsxref("Array.prototype.forEach()")}}。
+
{{jsxref("TypedArray.includes", "Uint8Array.prototype.includes()")}} {{experimental_inline}}
+
判断类型化数组是否包含特定值,如果包含返回 true,否则返回false。另见{{jsxref("Array.prototype.includes()")}}。
+
{{jsxref("TypedArray.indexOf", "Uint8Array.prototype.indexOf()")}}
+
返回数组中等于特定值的第一个元素(下标最小),如果没有找到则返回 -1,请参见 {{jsxref("Array.prototype.indexOf()")}}.
+
{{jsxref("TypedArray.join", "Uint8Array.prototype.join()")}}
+
将数组中所有元素连接为字符串。请参见 {{jsxref("Array.prototype.join()")}}。
+
{{jsxref("TypedArray.keys", "Uint8Array.prototype.keys()")}}
+
返回新的Array Iterator ,含有数组中每个下标的键,请参见 {{jsxref("Array.prototype.keys()")}}。
+
{{jsxref("TypedArray.lastIndexOf", "Uint8Array.prototype.lastIndexOf()")}}
+
返回数组中等于特定值的最后一个元素(下标最大),如果没有找到则返回 -1,请参见 {{jsxref("Array.prototype.lastIndexOf()")}}。
+
{{jsxref("TypedArray.map", "Uint8Array.prototype.map()")}}
+
使用在该数组的每个元素上调用函数的结果创建新数组,请参见{{jsxref("Array.prototype.map()")}}。
+
{{jsxref("TypedArray.move", "Uint8Array.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
+
{{jsxref("TypedArray.copyWithin", "Uint8Array.prototype.copyWithin()")}}的之前的非标准版本。
+
{{jsxref("TypedArray.reduce", "Uint8Array.prototype.reduce()")}}
+
对累加器和数组的每个值应用函数(从左到右),使其归约为单一的值, 另见 {{jsxref("Array.prototype.reduce()")}}。
+
{{jsxref("TypedArray.reduceRight", "Uint8Array.prototype.reduceRight()")}}
+
对累加器和数组的每个值应用函数(从右到左),使其归约为单一的值, 另见 {{jsxref("Array.prototype.reduceRight()")}}。
+
{{jsxref("TypedArray.reverse", "Uint8Array.prototype.reverse()")}}
+
翻转数组中的元素顺序 — 第一个变为最后,最后变为第一个。另见 {{jsxref("Array.prototype.reverse()")}}。
+
{{jsxref("TypedArray.set", "Uint8Array.prototype.set()")}}
+
在类型化数组中储存多个值,从特定数组中读取输入。
+
{{jsxref("TypedArray.slice", "Uint8Array.prototype.slice()")}}
+
提取数组的某个部分并返回新的数组,请参见 {{jsxref("Array.prototype.slice()")}}。
+
{{jsxref("TypedArray.some", "Uint8Array.prototype.some()")}}
+
如果数组中至少一个元素满足给定的测试函数,则返回true。请参见{{jsxref("Array.prototype.some()")}}。
+
{{jsxref("TypedArray.sort", "Uint8Array.prototype.sort()")}}
+
原地排序数组中的元素,并返回该数组,请参见 {{jsxref("Array.prototype.sort()")}}。
+
{{jsxref("TypedArray.subarray", "Uint8Array.prototype.subarray()")}}
+
从给定的元素起始和终止下标返回新的 Uint8Array 。
+
{{jsxref("TypedArray.values", "Uint8Array.prototype.values()")}}
+
返回新的 Array Iterator 对象,含有数组每个下标处的值,请参见 {{jsxref("Array.prototype.values()")}}。
+
{{jsxref("TypedArray.toLocaleString", "Uint8Array.prototype.toLocaleString()")}}
+
返回表示数组及其元素的本地化字符串,请参见 {{jsxref("Array.prototype.toLocaleString()")}}。
+
{{jsxref("TypedArray.toString", "Uint8Array.prototype.toString()")}}
+
返回表示数组及其元素的字符串。请参见 {{jsxref("Array.prototype.toString()")}}。
+
{{jsxref("TypedArray.@@iterator", "Uint8Array.prototype[@@iterator]()")}}
+
返回新的 Array Iterator 对象,包含数组中每个下标处的值。
+
+ +

例子

+ +
// 来自长度
+var uint8 = new Uint8Array(2);
+uint8[0] = 42;
+console.log(uint8[0]); // 42
+console.log(uint8.length); // 2
+console.log(uint8.BYTES_PER_ELEMENT); // 1
+
+// 来自数组
+var arr = new Uint8Array([21,31]);
+console.log(arr[1]); // 31
+
+// 来自另一个 TypedArray
+var x = new Uint8Array([21, 31]);
+var y = new Uint8Array(x);
+console.log(y[0]); // 21
+
+// 来自 ArrayBuffer
+var buffer = new ArrayBuffer(8);
+var z = new Uint8Array(buffer, 1, 4);
+
+// 来自一个迭代器
+var iterable = function*(){ yield* [1,2,3]; }();
+var uint8 = new Uint8Array(iterable);
+// Uint8Array[1, 2, 3]
+
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
类型化数组规范Obsolete由 ECMAScript 6 取代。
{{SpecName('ES6', '#table-45', 'TypedArray constructors')}}{{Spec2('ES6')}}ECMA 标准中的初始定义。
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Uint8Array")}}

+ +

兼容性说明

+ +

从 ECMAScript 2015 开始,Uint8Array 构造函数需要通过 {{jsxref("Operators/new", "new")}} 操作符调用。即日起如果没有使用 new 调用 Uint8Array 的构造函数,将会抛出 {{jsxref("TypeError")}} 。

+ +
var dv = Uint8Array([1, 2, 3]);
+// TypeError: calling a builtin Uint8Array constructor
+// 不使用 new 将会被禁止
+ +
var dv = new Uint8Array([1, 2, 3]);
+ +

相关内容

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/uint8clampedarray/index.html b/files/zh-cn/web/javascript/reference/global_objects/uint8clampedarray/index.html new file mode 100644 index 0000000000..86028a8fb9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/uint8clampedarray/index.html @@ -0,0 +1,280 @@ +--- +title: Uint8ClampedArray +slug: Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray +translation_of: Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray +--- +
{{JSRef}}
+ +

Uint8ClampedArray(8位无符号整型固定数组) 类型化数组表示一个由值固定在0-255区间的8位无符号整型组成的数组;如果你指定一个在 [0,255] 区间外的值,它将被替换为0或255;如果你指定一个非整数,那么它将被设置为最接近它的整数。(数组)内容被初始化为0。一旦(数组)被创建,你可以使用对象的方法引用数组里的元素,或使用标准的数组索引语法(即使用方括号标记)。

+ +

语法

+ +
new Uint8ClampedArray(length);
+new Uint8ClampedArray(typedArray);
+new Uint8ClampedArray(object);
+new Uint8ClampedArray(buffer [, byteOffset [, length]]);
+ +

关于构造函数语法和参数的更多信息,参见 TypedArray

+ +

属性

+ +
+
{{jsxref("TypedArray.BYTES_PER_ELEMENT", "Uint8ClampedArray.BYTES_PER_ELEMENT")}}
+
返回元素大小的一个数值。对 Uint8ClampedArray 而言是1。
+
{{jsxref("TypedArray.prototype.length", "Uint8ClampedArray.prototype.length")}}
+
静态长度属性值为0。对于实际长度(元素的数量),见 {{jsxref("TypedArray.prototype.length", "Uint8ClampedArray.prototype.length")}}。
+
{{jsxref("TypedArray.name", "Uint8ClampedArray.name")}}
+
返回构造函数名的字符串值。对 Uint8ClampedArray 类型而言:"Uint8ClampedArray"。
+
{{jsxref("TypedArray.prototype", "Uint8ClampedArray.prototype")}}
+
原型是 TypedArray (类型化数组)对象。
+
+ +

方法

+ +
+
{{jsxref("TypedArray.from", "Uint8ClampedArray.from()")}}
+
从一个类数组或可枚举对象创建一个新的 Uint8ClampedArray。参见 {{jsxref("Array.from()")}}。
+
{{jsxref("TypedArray.of", "Uint8ClampedArray.of()")}}
+
通过一个可选数量参数来创建一个新的 Uint8ClampedArray。参见 {{jsxref("Array.of()")}}。
+
+ +

Uint8ClampedArray 原型

+ +

所有的 Uint8ClampedArray 对象继承自 {{jsxref("TypedArray.prototype", "%TypedArray%.prototype")}}。

+ +

属性

+ +
+
Uint8ClampedArray.prototype.constructor
+
返回创建一个实例原型的函数。这是 Uint8ClampedArray 默认的构造函数。
+
{{jsxref("TypedArray.prototype.buffer", "Uint8ClampedArray.prototype.buffer")}} {{readonlyInline}}
+
返回由 Uint8ClampedArray 引用的 {{jsxref("ArrayBuffer")}} 。在创建时所固定下来,因此只能读取
+
{{jsxref("TypedArray.prototype.byteLength", "Uint8ClampedArray.prototype.byteLength")}} {{readonlyInline}}
+
返回从 {{jsxref("ArrayBuffer")}} 开始的 Uint8ClampedArray 的(字节的)长度。在创建时所固定下来,因此只能读取
+
{{jsxref("TypedArray.prototype.byteOffset", "Uint8ClampedArray.prototype.byteOffset")}} {{readonlyInline}}
+
返回从 {{jsxref("ArrayBuffer")}} 开始的 Uint8ClampedArray 的(字节的)偏移。在创建时所固定下来,因此只能读取
+
{{jsxref("TypedArray.prototype.length", "Uint8ClampedArray.prototype.length")}} {{readonlyInline}}
+
返回 UintClamped8Array 具有的元素数量。在创建时所固定下来,因此只能读取
+
+ +

方法

+ +
+
{{jsxref("TypedArray.copyWithin", "Uint8ClampedArray.prototype.copyWithin()")}}
+
复制数组内一段数组元素的序列。参见 {{jsxref("Array.prototype.copyWithin()")}}。
+
{{jsxref("TypedArray.entries", "Uint8ClampedArray.prototype.entries()")}}
+
返回一个新的包含数组中每个索引对应的键/值对的数组迭代器对象。参见 {{jsxref("Array.prototype.entries()")}}。
+
{{jsxref("TypedArray.every", "Uint8ClampedArray.prototype.every()")}}
+
测试数组里的所有元素是否通过所提供的函数的测试。参见 {{jsxref("Array.prototype.every()")}}。
+
{{jsxref("TypedArray.fill", "Uint8ClampedArray.prototype.fill()")}}
+
用一个固定值填充一个数组内的从起始索引到结束索引的全部元素。参见 {{jsxref("Array.prototype.fill()")}}。
+
{{jsxref("TypedArray.filter", "Uint8ClampedArray.prototype.filter()")}}
+
由该数组中所有经所提供的筛选函数返回为 true 的元素创建一个新数组。参见 {{jsxref("Array.prototype.filter()")}}。
+
{{jsxref("TypedArray.find", "Uint8ClampedArray.prototype.find()")}}
+
如果数组里的一个元素符合所提供的测试函数则返回找到的这个值,如果没有找到则返回 undefined。参见 {{jsxref("Array.prototype.find()")}}。
+
{{jsxref("TypedArray.findIndex", "Uint8ClampedArray.prototype.findIndex()")}}
+
如果数组里的一个元素符合所提供的测试函数则返回找到的索引,如果没有找到则返回 -1。参见 {{jsxref("Array.prototype.findIndex()")}}。
+
{{jsxref("TypedArray.forEach", "Uint8ClampedArray.prototype.forEach()")}}
+
对数组内的每个元素调用一个函数。参见 {{jsxref("Array.prototype.forEach()")}}。
+
{{jsxref("TypedArray.includes", "Uint8ClampedArray.prototype.includes()")}} {{experimental_inline}}
+
确定一个类型化数组是否包含一个特定的元素,对应地返回 true 或 false。参见 {{jsxref("Array.prototype.includes()")}}。
+
{{jsxref("TypedArray.indexOf", "Uint8ClampedArray.prototype.indexOf()")}}
+
Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.indexOf()")}}.
+
{{jsxref("TypedArray.join", "Uint8ClampedArray.prototype.join()")}}
+
Joins all elements of an array into a string. See also {{jsxref("Array.prototype.join()")}}.
+
{{jsxref("TypedArray.keys", "Uint8ClampedArray.prototype.keys()")}}
+
Returns a new Array Iterator that contains the keys for each index in the array. See also {{jsxref("Array.prototype.keys()")}}.
+
{{jsxref("TypedArray.lastIndexOf", "Uint8ClampedArray.prototype.lastIndexOf()")}}
+
Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. See also {{jsxref("Array.prototype.lastIndexOf()")}}.
+
{{jsxref("TypedArray.map", "Uint8ClampedArray.prototype.map()")}}
+
Creates a new array with the results of calling a provided function on every element in this array. See also {{jsxref("Array.prototype.map()")}}.
+
{{jsxref("TypedArray.move", "Uint8ClampedArray.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
+
Former non-standard version of {{jsxref("TypedArray.copyWithin", "Uint8ClampedArray.prototype.copyWithin()")}}.
+
{{jsxref("TypedArray.reduce", "Uint8ClampedArray.prototype.reduce()")}}
+
Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. See also {{jsxref("Array.prototype.reduce()")}}.
+
{{jsxref("TypedArray.reduceRight", "Uint8ClampedArray.prototype.reduceRight()")}}
+
Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. See also {{jsxref("Array.prototype.reduceRight()")}}.
+
{{jsxref("TypedArray.reverse", "Uint8ClampedArray.prototype.reverse()")}}
+
Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first. See also {{jsxref("Array.prototype.reverse()")}}.
+
{{jsxref("TypedArray.set", "Uint8ClampedArray.prototype.set()")}}
+
Stores multiple values in the typed array, reading input values from a specified array.
+
{{jsxref("TypedArray.slice", "Uint8ClampedArray.prototype.slice()")}}
+
Extracts a section of an array and returns a new array. See also {{jsxref("Array.prototype.slice()")}}.
+
{{jsxref("TypedArray.some", "Uint8ClampedArray.prototype.some()")}}
+
Returns true if at least one element in this array satisfies the provided testing function. See also {{jsxref("Array.prototype.some()")}}.
+
{{jsxref("TypedArray.sort", "Uint8ClampedArray.prototype.sort()")}}
+
Sorts the elements of an array in place and returns the array. See also {{jsxref("Array.prototype.sort()")}}.
+
{{jsxref("TypedArray.subarray", "Uint8ClampedArray.prototype.subarray()")}}
+
Returns a new Uint8ClampedArray from the given start and end element index.
+
{{jsxref("TypedArray.values", "Uint8ClampedArray.prototype.values()")}}
+
Returns a new Array Iterator object that contains the values for each index in the array. See also {{jsxref("Array.prototype.values()")}}.
+
{{jsxref("TypedArray.toLocaleString", "Uint8ClampedArray.prototype.toLocaleString()")}}
+
Returns a localized string representing the array and its elements. See also {{jsxref("Array.prototype.toLocaleString()")}}.
+
{{jsxref("TypedArray.toString", "Uint8ClampedArray.prototype.toString()")}}
+
Returns a string representing the array and its elements. See also {{jsxref("Array.prototype.toString()")}}.
+
{{jsxref("TypedArray.@@iterator", "Uint8ClampedArray.prototype[@@iterator]()")}}
+
Returns a new Array Iterator object that contains the values for each index in the array.
+
+ +

实例

+ +

创建一个 Uint8ClampedArray 的不同方式:

+ +
// From a length
+var uintc8 = new Uint8ClampedArray(2);
+uintc8[0] = 42;
+uintc8[1] = 1337;
+console.log(uintc8[0]); // 42
+console.log(uintc8[1]); // 255 (clamped)
+console.log(uintc8.length); // 2
+console.log(uintc8.BYTES_PER_ELEMENT); // 1
+
+// From an array
+var arr = new Uint8ClampedArray([21,31]);
+console.log(arr[1]); // 31
+
+// From another TypedArray
+var x = new Uint8ClampedArray([21, 31]);
+var y = new Uint8ClampedArray(x);
+console.log(y[0]); // 21
+
+// From an ArrayBuffer
+var buffer = new ArrayBuffer(8);
+var z = new Uint8ClampedArray(buffer, 1, 4);
+
+// From an iterable
+var iterable = function*(){ yield* [1,2,3]; }();
+var uintc8 = new Uint8ClampedArray(iterable);
+// Uint8ClampedArray[1, 2, 3]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}已由 ECMAScript 2015 替代。
{{SpecName('ES6', '#table-49', 'TypedArray constructors')}}{{Spec2('ES6')}}最初定义在一份 ECMA 标准中。规定 new 是必需的。
{{SpecName('ESDraft', '#table-49', 'TypedArray constructors')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基础支持7.0{{ CompatGeckoDesktop(2) }}11 (as of KB2929437)11.65.1
需要使用 new{{CompatUnknown}}{{ CompatGeckoDesktop(44) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
构造函数中可枚举{{CompatUnknown}}{{ CompatGeckoDesktop(52) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础支持4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile(2) }}{{CompatVersionUnknown}}11.64.2
需要使用 new{{CompatUnknown}}{{CompatUnknown}}{{ CompatGeckoMobile(44) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
构造函数中可枚举{{CompatUnknown}}{{CompatUnknown}}{{ CompatGeckoMobile(52) }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

兼容性注意事项

+ +

从 ECMAScript 2015 开始, Uint8ClampedArray 构造函数需要用一个 {{jsxref("Operators/new", "new")}} 操作符来构建。从现在开始,不使用 new 来调用一个 Uint8ClampedArray 构造函数将会抛出一个 {{jsxref("TypeError")}}。

+ +
var dv = Uint8ClampedArray([1, 2, 3]);
+// TypeError: calling a builtin Uint8ClampedArray constructor
+// without new is forbidden
+ +
var dv = new Uint8ClampedArray([1, 2, 3]);
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/undefined/index.html b/files/zh-cn/web/javascript/reference/global_objects/undefined/index.html new file mode 100644 index 0000000000..71a33f157d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/undefined/index.html @@ -0,0 +1,138 @@ +--- +title: undefined +slug: Web/JavaScript/Reference/Global_Objects/undefined +translation_of: Web/JavaScript/Reference/Global_Objects/undefined +--- +
+
+
{{jsSidebar("Objects")}}
+ +
全局属性undefined表示原始值{{Glossary("Undefined", "undefined")}}。它是一个JavaScript的 {{Glossary("Primitive", "原始数据类型")}} 。
+ +
+ +
{{js_property_attributes(0,0,0)}}
+ +
+ +
+
{{EmbedInteractiveExample("pages/js/globalprops-undefined.html")}}
+
+
+
+ +

语法

+ +
undefined 
+ +

描述

+ +

undefined全局对象的一个属性。也就是说,它是全局作用域的一个变量。undefined的最初值就是原始数据类型{{Glossary("Undefined", "undefined")}}

+ +

在现代浏览器(JavaScript 1.8.5/Firefox 4+),自ECMAscript5标准以来undefined是一个不能被配置(non-configurable),不能被重写(non-writable)的属性。即便事实并非如此,也要避免去重写它。

+ +

一个没有被赋值的变量的类型是undefined。如果方法或者是语句中操作的变量没有被赋值,则会返回undefined(对于这句话持疑惑态度,请查看英文原文来理解)。

+ +
function test(a){
+    console.log(typeof a);    // undefined
+    return a;
+}
+
+test();                       // 返回"undefined"
+ +

一个函数如果没有使用return语句指定{{jsxref("Statements/return", "返回")}}值,就会返回一个undefined值。

+ +
+

但是它有可能在非全局作用域中被当作{{Glossary("Identifier", "标识符")}}(变量名)来使用(因为undefined不是一个{{jsxref("Reserved_Words", "保留字")}})),这样做是一个非常坏的主意,因为这样会使你的代码难以去维护和排错。

+ +
// 不要这样做!
+
+// 打印 'foo string' PS:说明undefined的值和类型都已经改变
+(function() {
+var undefined = 'foo';
+console.log(undefined, typeof undefined)
+})()
+
+// 打印 'foo string' PS:说明undefined的值和类型都已经改变
+(function(undefined) {
+console.log(undefined, typeof undefined)
+})('foo')
+
+
+
+ +

示例

+ +

严格相等和undefined

+ +

你可以使用undefined和严格相等或不相等操作符来决定一个变量是否拥有值。在下面的代码中,变量x是未定义的,if 语句的求值结果将是true

+ +
var x;
+
+if (x === undefined) {
+// 执行这些语句
+} else {
+// 这些语句不会被执行
+}
+ +
+

注意:这里是必须使用严格相等操作符(===)而不是标准相等操作符(==),因为 x == undefined 会检查x是不是null,但是严格相等不会检查(有点饶人,其实 === 会严格判断双方的类型、值等是否相等)。null不等同于undefined。移步{{jsxref("Operators/Comparison_Operators", "比较操作符")}}查看详情。

+
+ +

Typeof 操作符和undefined

+ +

或者,可以使用{{jsxref("Operators/typeof", "typeof")}}:

+ +
var x;
+if(typeof x === 'undefined') {
+    // 执行这些语句
+}
+ +

使用 {{jsxref("Operators/typeof", "typeof")}}的原因是它不会在一个变量没有被声明的时候抛出一个错误。

+ +
// 这里没有声明y
+if(typeof y === 'undefined') {       // 没有错误,执行结果为true
+   console.log("y is " + typeof y )  // y is undefined
+}
+
+if(y === undefined) {                // ReferenceError: y is not defined
+
+}
+ +

但是,技术方面看来这样的使用方法应该被避免。JavaScript是一个静态作用域语言,所以,一个变量是否被声明可以通过看它是否在一个封闭的上下文中被声明。唯一的例外是全局作用域,但是全局作用域是被绑定在全局对象上的,所以要检查一个变量是否在全局上下文中存在可以通过检查全局对象上是否存在这个属性(比如使用{{jsxref("Operators/in", "in")}}操作符)。

+ +
if ('x' in window) {
+  // 只有x被全局性的定义 才会这行这些语句
+}
+ +

Void操作符和undefined

+ +

{{jsxref("Operators/void", "void")}} 操作符是第三种可以替代的方法。

+ +
var x;
+if(x === void 0) {
+    // 执行这些语句
+}
+
+// 没有声明y
+if(y === void 0) {
+    // 抛出一个RenferenceError错误(与`typeof`相比)
+}
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-undefined', 'undefined')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.undefined")}}

diff --git a/files/zh-cn/web/javascript/reference/global_objects/unescape/index.html b/files/zh-cn/web/javascript/reference/global_objects/unescape/index.html new file mode 100644 index 0000000000..b85895a7cd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/unescape/index.html @@ -0,0 +1,84 @@ +--- +title: unescape() +slug: Web/JavaScript/Reference/Global_Objects/unescape +tags: + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/unescape +--- +
{{jsSidebar("Objects")}}
+ +

已废弃的unescape() 方法计算生成一个新的字符串,其中的十六进制转义序列将被其表示的字符替换。上述的转义序列就像{{jsxref("escape")}}里介绍的一样。因为 unescape 已经废弃,建议使用 {{jsxref("decodeURI")}}或者{{jsxref("decodeURIComponent")}} 替代本方法。

+ +
注意:不要使用unescape去解码URLS,使用decodeURI替代。
+ +

语法

+ +
unescape(str)
+ +

参数

+ +
+
str
+
被编码过的字符串。
+
+

返回值

+
+
一个未被转义的新字符串。
+
+ +

描述

+ +

unescape函数是全局对象的一个属性。

+ +

示例

+ +
unescape('abc123');     // "abc123"
+unescape('%E4%F6%FC');  // "äöü"
+unescape('%u0107');     // "ć"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1', '#sec-15.1.2.5', 'unescape')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-B.2.2', 'unescape')}}{{Spec2('ES5.1')}}Defined in the (informative) Compatibility Annex B
{{SpecName('ES6', '#sec-unescape-string', 'unescape')}}{{Spec2('ES6')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers
{{SpecName('ESDraft', '#sec-unescape-string', 'unescape')}}{{Spec2('ESDraft')}}Defined in the (normative) Annex B for Additional ECMAScript Features for Web Browsers
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.unescape")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/uneval/index.html b/files/zh-cn/web/javascript/reference/global_objects/uneval/index.html new file mode 100644 index 0000000000..38d7959076 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/uneval/index.html @@ -0,0 +1,68 @@ +--- +title: uneval() +slug: Web/JavaScript/Reference/Global_Objects/uneval +tags: + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/uneval +--- +
{{jsSidebar("Objects")}}{{Non-standard_header}}
+ +

uneval() 函数创建一个代表对象的源代码的字符串。

+ +

语法

+ +
uneval(object)
+ +

参数

+ +
+
object
+
JavaScript 表达式或者语句
+
+ +

返回值

+ +
+
表示给定对象的源代码的字符串
+
+ +
注意:无法通过此方法获取对象的 JSON 形式。
+ +

描述

+ +

uneval() 是一个顶级函数并且不与任何对象关联

+ +

实例

+ +
var a = 1;
+uneval(a); // returns a String containing 1
+
+var b = "1";
+uneval(b) // returns a String containing "1"
+
+uneval(function foo(){}); // returns "(function foo(){})"
+
+
+var a = uneval(function foo(){return 'hi'});
+var foo = eval(a);
+foo(); // returns "hi"
+
+ +

规范

+ +

不属于任何规范的一部分。

+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.uneval")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/urierror/index.html b/files/zh-cn/web/javascript/reference/global_objects/urierror/index.html new file mode 100644 index 0000000000..980de3b3c6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/urierror/index.html @@ -0,0 +1,136 @@ +--- +title: URIError +slug: Web/JavaScript/Reference/Global_Objects/URIError +tags: + - Error + - JavaScript + - URIError + - 对象 +translation_of: Web/JavaScript/Reference/Global_Objects/URIError +--- +
{{JSRef}}
+ +

URIError 对象用来表示以一种错误的方式使用全局URI处理函数而产生的错误。

+ +

语法

+ +
new URIError([message[, fileName[, lineNumber]]])
+ +

参数

+ +
+
message
+
选填。易于理解的错误描述。
+
fileName 【非标准内联】
+
选填。包含造成异常的代码的文件名称。
+
lineNumber 【非标准内联】
+
选填。造成异常的代码行号。
+
+ +

描述

+ +

当向全局 URI 处理函数传递一个不合法的URI时,URIError 错误会被抛出。

+ +

属性

+ +
+
{{jsxref("URIError.prototype")}}
+
允许向一个 URIError 对象添加额外的属性。
+
+ +

方法

+ +

虽然全局 URIError 对象没有任何自己的方法,但是它能通过原型链继承一些方法。

+ +

URIError 实例

+ +

属性

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/URIError/prototype', '属性')}}
+ +

方法

+ +
{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/URIError/prototype', '方法')}}
+ +

示例

+ +

捕获一个 URIError 实例

+ +
try {
+  decodeURIComponent('%');
+} catch (e) {
+  console.log(e instanceof URIError); // true
+  console.log(e.message);             // "malformed URI sequence"
+  console.log(e.name);                // "URIError"
+  console.log(e.fileName);            // "Scratchpad/1"
+  console.log(e.lineNumber);          // 2
+  console.log(e.columnNumber);        // 2
+  console.log(e.stack);               // "@Scratchpad/2:2:3\n"
+}
+
+ +

创建一个 URIError 实例

+ +
try {
+  throw new URIError('Hello', 'someFile.js', 10);
+} catch (e) {
+  console.log(e instanceof URIError); // true
+  console.log(e.message);             // "Hello"
+  console.log(e.name);                // "URIError"
+  console.log(e.fileName);            // "someFile.js"
+  console.log(e.lineNumber);          // 10
+  console.log(e.columnNumber);        // 0
+  console.log(e.stack);               // "@Scratchpad/2:2:9\n"
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ES3', '#sec-15.11.6.6', 'URIError')}}{{Spec2('ES3')}}初始定义
{{SpecName('ES5.1', '#sec-15.11.6.6', 'URIError')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-native-error-types-used-in-this-standard-urierror', 'URIError')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-native-error-types-used-in-this-standard-urierror', 'URIError')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.builtins.URIError")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/urierror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/urierror/prototype/index.html new file mode 100644 index 0000000000..f011159690 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/urierror/prototype/index.html @@ -0,0 +1,82 @@ +--- +title: URIError.prototype +slug: Web/JavaScript/Reference/Global_Objects/URIError/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/URIError +--- +
{{JSRef}}
+ +
URIError.prototype 属性表示 {{jsxref("URIError")}} 构造器的原型。
+ +

描述

+ +

所有的 {{jsxref("URIError")}} 实例都继承自 URIError.prototype。 可以通过原型(prototype) 给所有的实例添加属性或者方法。

+ +

属性

+ +
+
URIError.prototype.constructor
+
声明创建实例原型 (prototype) 的方法。
+
{{jsxref("Error.prototype.message", "URIError.prototype.message")}}
+
错误信息。虽然 ECMA-262 规范指出 {{jsxref("URIError")}} 应该提供其自己专属的 message 属性,但是在 SpiderMonkey 中,该属性继承自 {{jsxref("Error.prototype.message")}}
+
{{jsxref("Error.prototype.name", "URIError.prototype.name")}}
+
错误名称。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.fileName", "URIError.prototype.fileName")}}
+
产生该错误的代码所在文件的路径。 继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.lineNumber", "URIError.prototype.lineNumber")}}
+
产生该错误的代码所在行的行号。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.columnNumber", "URIError.prototype.columnNumber")}}
+
产生该错误的代码所在列的列号。 继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.stack", "URIError.prototype.stack")}}
+
堆栈记录。继承自 {{jsxref("Error")}}。
+
+ +

方法

+ +

虽然 {{jsxref("URIError")}} 的原型对象自身不包含任何方法,但是 {{jsxref("URIError")}} 的实例通过原型链(prototype chain)继承了一些方法。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES3')}} 初始定义
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}} 定义为 NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}} 定义为NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}} 定义为NativeError.prototype.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.URIError")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakmap/clear/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakmap/clear/index.html new file mode 100644 index 0000000000..b2d51c64a1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakmap/clear/index.html @@ -0,0 +1,104 @@ +--- +title: WeakMap.prototype.clear() +slug: Web/JavaScript/Reference/Global_Objects/WeakMap/clear +tags: + - JavaScript + - Method + - WeakMap + - clear() +translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap/clear +--- +
{{JSRef}} {{obsolete_header}}
+ +

clear()用来从 WeakMap对象中移除所有元素。但不再是ECMAScript和它的实现部分。

+ +
+

Warning:

+ +

WeakMap(no clear() any more).png

+
+ +

语法

+ +
wm.clear();
+ +

示例

+ +

使用 clear 方法

+ +
var wm = new WeakMap();
+var obj = {};
+
+wm.set(obj, "foo");
+wm.set(window, "bar");
+
+wm.has(obj); // true
+wm.has(window); // true
+
+wm.clear();
+
+wm.has(obj)  // false
+wm.has(window)  // false
+
+ +

规范

+ +

当前版本或者起草中没有这个方法,这个方法在版本 28(2014 年 10 月 14) 之前是 ECMAScript 6 起草规范的一部分,但是在起草之后的版本中被移除了。它不在是最终标准的一部分了 。

+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatNo}} [1]11237.1
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}} [1]{{CompatNo}}{{CompatNo}}8
+
+ +

[1] The clear() 曾经在高于 20 版本低于 45 版本之间被支持。

+ +

相近

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakmap/delete/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakmap/delete/index.html new file mode 100644 index 0000000000..337563ecd3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakmap/delete/index.html @@ -0,0 +1,108 @@ +--- +title: WeakMap.prototype.delete() +slug: Web/JavaScript/Reference/Global_Objects/WeakMap/delete +translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap/delete +--- +
{{JSRef("Global_Objects", "WeakMap")}}
+ +

概述

+ +

delete() 方法可以从一个 WeakMap 对象中删除指定的元素。

+ +

语法

+ +
wm.delete(key);
+ +

Parameters参数

+ +
+
key
+
需要删除的元素的键
+
+ +

返回值

+ +

如果成功删除,返回 true,否则返回 false

+ +

示例

+ +
var wm = new WeakMap();
+wm.set(window, "foo");
+
+wm.delete(window); // 返回 true,表示删除成功。
+
+wm.has(window);    // 返回 false,因为 window 对象已经被删除了。
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakmap.prototype.delete', 'WeakMap.prototype.delete')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (SpiderMonkey)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}[1]{{CompatGeckoDesktop("6.0")}}11{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (SpiderMonkey)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatGeckoMobile("6.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakmap/get/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakmap/get/index.html new file mode 100644 index 0000000000..5dd596c3ff --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakmap/get/index.html @@ -0,0 +1,120 @@ +--- +title: WeakMap.prototype.get() +slug: Web/JavaScript/Reference/Global_Objects/WeakMap/get +translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap/get +--- +
{{JSRef}}
+ +

get() 方法返回  WeakMap 指定的元素。

+ +

语法

+ +
wm.get(key);
+ +

参数

+ +
+
key
+
必须。 想要从 WeakMap 获取的元素的键。
+
+ +

返回值

+ +

返回与指定键相关联的值,如果 WeakMap 对象找不到这个键则返回 undefined

+ +

例子

+ +

使用 get 方法 

+ +
var wm = new WeakMap();
+wm.set(window, "foo");
+
+wm.get(window); // 返回 "foo".
+wm.get("baz");  // 返回 undefined.
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakmap.prototype.get', 'WeakMap.prototype.get')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakmap.prototype.get', 'WeakMap.prototype.get')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatGeckoDesktop("6.0")}}11237.1
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatGeckoMobile("6.0")}}{{CompatNo}}{{CompatNo}}8
+
+ +

Firefox 中的注意事项

+ + + +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakmap/has/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakmap/has/index.html new file mode 100644 index 0000000000..2c411d429d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakmap/has/index.html @@ -0,0 +1,123 @@ +--- +title: WeakMap.prototype.has() +slug: Web/JavaScript/Reference/Global_Objects/WeakMap/has +translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap/has +--- +
{{JSRef}}
+ +

 has() 方法根据WeakMap对象的元素中是否存在key键返回一个boolean值。

+ +

语法

+ +
wm.has(key);
+ +

Parameters

+ +
+
key
+
必须的。用来检测WeakMap对象中是否存在元素的键为key。
+
+ +

Return value

+ +
+
Boolean
+
如果指定的key存在于某个元素中则返回true,否则返回flase。
+
+ +

例子

+ +

使用 has方法

+ +
var wm = new WeakMap();
+wm.set(window, "foo");
+
+wm.has(window); // returns true
+wm.has("baz");  // returns false
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakmap.prototype.has', 'WeakMap.prototype.has')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakmap.prototype.has', 'WeakMap.prototype.has')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatGeckoDesktop("6.0")}}11237.1
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatGeckoMobile("6.0")}}{{CompatNo}}{{CompatNo}}8
+
+ +

Firefox-特有说明

+ + + +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakmap/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakmap/index.html new file mode 100644 index 0000000000..936763d12f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakmap/index.html @@ -0,0 +1,159 @@ +--- +title: WeakMap +slug: Web/JavaScript/Reference/Global_Objects/WeakMap +tags: + - ECMAScript 2015 + - JavaScript + - WeakMap +translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap +--- +
{{JSRef}}
+ +

WeakMap 对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的。

+ +

你可以从这里了解更多关于WeakMap的内容:{{SectionOnPage("/zh-CN/docs/Web/JavaScript/Guide/Keyed_collections", "WeakMap对象")}}.

+ +

语法

+ +
new WeakMap([iterable])
+ +

参数

+ +
+
iterable
+
Iterable 是一个数组(二元数组)或者其他可迭代的且其元素是键值对的对象。每个键值对会被加到新的 WeakMap 里。null 会被当做 undefined。
+
+ +

描述

+ +

WeakMap 的 key 只能是 Object 类型。 {{Glossary("Primitive", "原始数据类型")}} 是不能作为 key 的(比如 {{jsxref("Symbol")}})。

+ +

Why WeakMap?

+ +

在 JavaScript 里,map API 可以通过使其四个 API 方法共用两个数组(一个存放键,一个存放值)来实现。给这种 map 设置值时会同时将键和值添加到这两个数组的末尾。从而使得键和值的索引在两个数组中相对应。当从该 map 取值的时候,需要遍历所有的键,然后使用索引从存储值的数组中检索出相应的值。

+ +

但这样的实现会有两个很大的缺点,首先赋值和搜索操作都是 O(n) 的时间复杂度( n 是键值对的个数),因为这两个操作都需要遍历全部整个数组来进行匹配。另外一个缺点是可能会导致内存泄漏,因为数组会一直引用着每个键和值。这种引用使得垃圾回收算法不能回收处理他们,即使没有其他任何引用存在了。

+ +

相比之下,原生的 WeakMap 持有的是每个键对象的“弱引用”,这意味着在没有其他引用存在时垃圾回收能正确进行。原生 WeakMap 的结构是特殊且有效的,其用于映射的 key 只有在其没有被回收时才是有效的。

+ +

正由于这样的弱引用,WeakMap 的 key 是不可枚举的 (没有方法能给出所有的 key)。如果key 是可枚举的话,其列表将会受垃圾回收机制的影响,从而得到不确定的结果。因此,如果你想要这种类型对象的 key 值的列表,你应该使用 {{jsxref("Map")}}。

+ +

基本上,如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap。

+ +

属性

+ +
+
WeakMap.length
+
length  属性的值为 0。
+
{{jsxref("WeakMap.prototype")}}
+
WeakMap 构造器的原型。 允许添加属性到所有的 WeakMap 对象。
+
+ +

WeakMap 实例

+ +

所有 WeakMap 实例继承自 {{jsxref("WeakMap.prototype")}}.

+ +

属性

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/WeakMap/prototype','属性')}}

+ +

方法

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/WeakMap/prototype','方法')}}

+ +

示例

+ +

使用 WeakMap

+ +
const wm1 = new WeakMap(),
+      wm2 = new WeakMap(),
+      wm3 = new WeakMap();
+const o1 = {},
+      o2 = function(){},
+      o3 = window;
+
+wm1.set(o1, 37);
+wm1.set(o2, "azerty");
+wm2.set(o1, o2); // value可以是任意值,包括一个对象或一个函数
+wm2.set(o3, undefined);
+wm2.set(wm1, wm2); // 键和值可以是任意对象,甚至另外一个WeakMap对象
+
+wm1.get(o2); // "azerty"
+wm2.get(o2); // undefined,wm2中没有o2这个键
+wm2.get(o3); // undefined,值就是undefined
+
+wm1.has(o2); // true
+wm2.has(o2); // false
+wm2.has(o3); // true (即使值是undefined)
+
+wm3.set(o1, 37);
+wm3.get(o1); // 37
+
+wm1.has(o1);   // true
+wm1.delete(o1);
+wm1.has(o1);   // false
+
+ +

实现一 个带有 .clear() 方法的类 WeakMap

+ +
class ClearableWeakMap {
+  constructor(init) {
+    this._wm = new WeakMap(init)
+  }
+  clear() {
+    this._wm = new WeakMap()
+  }
+  delete(k) {
+    return this._wm.delete(k)
+  }
+  get(k) {
+    return this._wm.get(k)
+  }
+  has(k) {
+    return this._wm.has(k)
+  }
+  set(k, v) {
+    this._wm.set(k, v)
+    return this
+  }
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakmap-objects', 'WeakMap')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakmap-objects', 'WeakMap')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +
{{Compat("javascript.builtins.WeakMap")}}
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakmap/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakmap/prototype/index.html new file mode 100644 index 0000000000..706b6d795c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakmap/prototype/index.html @@ -0,0 +1,137 @@ +--- +title: WeakMap.prototype +slug: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap +--- +
{{JSRef}}
+ +

WeakMap.prototype属性表现为 {{jsxref("WeakMap")}}的构造器。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

{{jsxref("WeakMap")}} 实例从 {{jsxref("WeakMap.prototype")}}继承了所有属性。你可以在WeakMap构造器中添加属性和方法,从而使得所有实例中都有效。

+ +

WeakMap.prototype 本身只是一个普通的对象:

+ +
Object.prototype.toString.call(WeakMap.prototype); // "[object Object]"
+ +

属性

+ +
+
WeakMap.prototype.constructor
+
返回创建WeakMap实例的原型函数。 {{jsxref("WeakMap")}}函数是默认的。
+
+ +

方法

+ +
+
{{jsxref("WeakMap.delete", "WeakMap.prototype.delete(key)")}}
+
移除key的关联对象。执行后 WeakMap.prototype.has(key)返回false。
+
{{jsxref("WeakMap.get", "WeakMap.prototype.get(key)")}}
+
返回key关联对象, 或者 undefined(没有key关联对象时)。
+
{{jsxref("WeakMap.has", "WeakMap.prototype.has(key)")}}
+
根据是否有key关联对象返回一个Boolean值。
+
{{jsxref("WeakMap.set", "WeakMap.prototype.set(key, value)")}}
+
在WeakMap中设置一组key关联对象,返回这个 WeakMap对象。
+
{{jsxref("WeakMap.prototype.clear()")}} {{obsolete_inline}}
+
WeakMap中移除所有的 key/value 。 注意,该方法已弃用,但可以通过创建一个空的WeakMap并替换原对象来实现 (参看 {{jsxref("WeakMap")}}的后半部分)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatGeckoDesktop("6.0")}}11237.1
Ordinary object{{CompatUnknown}}{{CompatGeckoDesktop("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("6.0")}}{{CompatNo}}{{CompatNo}}8
Ordinary object{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakmap/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakmap/set/index.html new file mode 100644 index 0000000000..9643d66bfd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakmap/set/index.html @@ -0,0 +1,89 @@ +--- +title: WeakMap.prototype.set() +slug: Web/JavaScript/Reference/Global_Objects/WeakMap/set +tags: + - JavaScript + - Method + - WeakMap +translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap/set +--- +
{{JSRef}}
+ +

set() 方法根据指定的keyvalue在 WeakMap对象中添加新/更新元素。

+ +
{{EmbedInteractiveExample("pages/js/weakmap-prototype-set.html")}}
+ + + +

语法

+ +
wm.set(key, value);
+ +

参数

+ +
+
key
+
必须的。必须是对象。是要在WeakMap 对象中添加元素的key部分。
+
value
+
必须的。任意的值。是要在WeakMap 对象中添加/元素的value部分。
+
+ +

返回值

+ +

WeakMap对象

+ +

例子

+ +

使用set方法

+ +
var wm = new WeakMap();
+var obj = {};
+
+// Add new elements to the WeakMap
+wm.set(obj, "foo").set(window, "bar"); // chainable
+
+// Update an element in the WeakMap
+wm.set(obj, "baz");
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakmap.prototype.set', 'WeakMap.prototype.set')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakmap.prototype.set', 'WeakMap.prototype.set')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.WeakMap.set")}}

+ +

Firefox-特殊说明

+ + + +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakref/deref/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakref/deref/index.html new file mode 100644 index 0000000000..9d9fdbdba1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakref/deref/index.html @@ -0,0 +1,69 @@ +--- +title: WeakRef.prototype.deref() +slug: Web/JavaScript/Reference/Global_Objects/WeakRef/deref +translation_of: Web/JavaScript/Reference/Global_Objects/WeakRef/deref +--- +
{{JSRef}}
+ +
+ +
deref方法返回{{jsxref("WeakRef")}} 实例的目标对象,如果目标对象已被垃圾收集,则返回undefined
+ +

语法

+ +
obj = ref.deref();
+
+ +

返回值

+ +

返回WeakRef的目标对象,如果该对象已被垃圾收集,则返回undefined

+ +

说明

+ +

有关一些重要说明,请参阅{{jsxref("WeakRef")}}页面上的Notes on WeakRefs

+ +

例子

+ +

使用deref

+ +

有关完整示例,请参阅{{jsxref("WeakRef")}}页面的示例部分。

+ +
const tick = () => {
+  // Get the element from the weak reference, if it still exists
+  const element = this.ref.deref();
+  if (element) {
+    element.textContent = ++this.count;
+  } else {
+    // The element doesn't exist anymore
+    console.log("The element is gone.");
+    this.stop();
+    this.ref = null;
+  }
+};
+ +

规范

+ + + + + + + + + + + + +
规范
{{SpecName('WeakRefs', '#sec-weak-ref.prototype.deref', 'WeakRef.prototype.deref()')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.WeakRef.deref")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakref/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakref/index.html new file mode 100644 index 0000000000..91452cd75f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakref/index.html @@ -0,0 +1,144 @@ +--- +title: WeakRef +slug: Web/JavaScript/Reference/Global_Objects/WeakRef +translation_of: Web/JavaScript/Reference/Global_Objects/WeakRef +--- +
{{JSRef}}
+ +
+ +

WeakRef对象允许您保留对另一个对象的弱引用,而不会阻止被弱引用对象被GC回收

+ +

描述

+ +

WeakRef对象包含对对象的弱引用,这个弱引用被称为该WeakRef对象的target或者是referent。对对象的弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为。而与此相反的,一个普通的引用(默认是强引用)会将与之对应的对象保存在内存中。只有当该对象没有任何的强引用时,JavaScript引擎GC才会销毁该对象并且回收该对象所占的内存空间。如果上述情况发生了,那么你就无法通过任何的弱引用来获取该对象。

+ +
+

Note: 在使用前请阅读Avoid where possible,对于WeakRef对象的使用要慎重考虑,能不使用就尽量不要使用

+
+ +

构造函数

+ +
+
{{jsxref("WeakRef/WeakRef", "WeakRef()")}}
+
创建一个WeakRef对象
+
+ +

实例方法

+ +
+
{{jsxref("WeakRef.deref", "WeakRef.prototype.deref()")}}
+
返回当前实例的WeakRef对象所绑定的target对象,如果该target对象已被GC回收则返回undefined
+
+ +

为什么尽量避免使用

+ +

正确使用WeakRef对象需要仔细的考虑,最好尽量避免使用。避免依赖于规范没有保证的任何特定行为也是十分重要的。何时、如何以及是否发生垃圾回收取决于任何给定JavaScript引擎的实现。GC在一个JavaScript引擎中的行为有可能在另一个JavaScript引擎中的行为大相径庭,或者甚至在同一类引擎,不同版本中GC的行为都有可能有较大的差距。GC目前还是JavaScript引擎实现者不断改进和改进解决方案的一个难题。

+ +

以下是WeakRef提案的作者在其解释文件(explainer document)中提出的一些具体观点

+ +
+

Garbage collectors are complicated. If an application or library depends on GC cleaning up a WeakRef or calling a finalizer [cleanup callback] in a timely, predictable manner, it's likely to be disappointed: the cleanup may happen much later than expected, or not at all. Sources of variability include:

+ + +
+ +

关于WeakRefs的说明

+ +

关于WeakRefs的一些说明

+ + + +

例子

+ +

使用WeakRef对象

+ +

这个例子演示了在一个DOM元素中启动一个计数器,当这个元素不存在时停止:

+ +
class Counter {
+  constructor(element) {
+    // Remember a weak reference to the DOM element
+    this.ref = new WeakRef(element);
+    this.start();
+  }
+
+  start() {
+    if (this.timer) {
+      return;
+    }
+
+    this.count = 0;
+
+    const tick = () => {
+      // Get the element from the weak reference, if it still exists
+      const element = this.ref.deref();
+      if (element) {
+        element.textContent = ++this.count;
+      } else {
+        // The element doesn't exist anymore
+        console.log("The element is gone.");
+        this.stop();
+        this.ref = null;
+      }
+    };
+
+    tick();
+    this.timer = setInterval(tick, 1000);
+  }
+
+  stop() {
+    if (this.timer) {
+      clearInterval(this.timer);
+      this.timer = 0;
+    }
+  }
+}
+
+const counter = new Counter(document.getElementById("counter"));
+counter.start();
+setTimeout(() => {
+  document.getElementById("counter").remove();
+}, 5000);
+
+ +

规范

+ + + + + + + + + + + + +
规范
WeakRefs proposal
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.WeakRef")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakset/add/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakset/add/index.html new file mode 100644 index 0000000000..d163451c4c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakset/add/index.html @@ -0,0 +1,121 @@ +--- +title: WeakSet.prototype.add() +slug: Web/JavaScript/Reference/Global_Objects/WeakSet/add +tags: + - ECMAScript 2015 + - JavaScript + - WeakSet +translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet/add +--- +
{{JSRef}}
+ +

add() 方法在 WeakSet 对象的最后一个元素后添加新的对象。

+ +

语法

+ +
ws.add(value);
+
+ +

参数

+ +
+
value
+
必须。 将对象添加进 WeakSet 集合中。
+
+ +

返回值

+ +

WeakSet 对象。

+ +

使用 add 方法

+ +
var ws = new WeakSet();
+
+ws.add(window); // 添加 window 对象进 WeakSet 中
+
+ws.has(window); // true
+
+// Weakset 仅取得对象作为参数
+ws.add(1);
+// 结果为 "TypeError: Invalid value used in weak set" 在 Chrome 浏览器中
+// 并且 "TypeError: 1 is not a non-null object" 在 Firefox 浏览器中
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-weakset.prototype.add', 'WeakSet.prototype.add')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakset.prototype.add', 'WeakSet.prototype.add')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatGeckoDesktop(34)}}{{CompatNo}}23{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{ CompatGeckoMobile(34) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakset/clear/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakset/clear/index.html new file mode 100644 index 0000000000..7d1e17ee9d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakset/clear/index.html @@ -0,0 +1,94 @@ +--- +title: WeakSet.prototype.clear() +slug: Web/JavaScript/Reference/Global_Objects/WeakSet/clear +tags: + - JavaScript + - Method + - WeakSet + - 废弃 +translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet/clear +--- +
{{JSRef}} {{obsolete_header}}
+ +

clear() 方法用于删除 WeakSet 对象的所有元素,但是已经不是 ECMAScript 的一部分了。

+ +

语法

+ +
ws.clear();
+ +

示例

+ +

使用 clear方法

+ +
var ws = new WeakSet();
+
+ws.add(window);
+ws.has(window);  // true
+
+ws.clear();
+
+ws.has(window); // false
+
+ +

规范

+ +

没有规范或草案。该方法原本计划包括在 ECMAScript 6,但是在草案 revision 28 (October 14, 2014) 被抛弃了。浏览器原先的实现不久后也被移除了,它从来不是标准的一分子。

+ +

浏览器支持

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatNo}} [1]{{CompatNo}}23{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}} [1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Added to Firefox in version 34, but removed in version 46. See {{bug(1101817)}}.

+ +

相关

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakset/delete/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakset/delete/index.html new file mode 100644 index 0000000000..82b35b0a7d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakset/delete/index.html @@ -0,0 +1,117 @@ +--- +title: WeakSet.prototype.delete() +slug: Web/JavaScript/Reference/Global_Objects/WeakSet/delete +translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet/delete +--- +
{{JSRef}}
+ +

delete() 方法从 WeakSet 对象中移除指定的元素。

+ +

语法

+ +
ws.delete(value);
+ +

参数

+ +
+
value
+
必须。从 WeakSet 对象中移除的对象。
+
+ +

返回值

+ +

如果在 WeakSet 对象中成功移除元素则返回 true。如果 key 没有在 WeakSet 中找到或者 key 不是一个对象,则返回 false。

+ +

示例

+ +

使用 delete 方法

+ +
var ws = new WeakSet();
+var obj = {};
+
+ws.add(window);
+
+ws.delete(obj);    // 返回 false。因为找不到要删除的obj
+ws.delete(window); // 返回 true。成功地移除了元素
+
+ws.has(window);    // 返回 false。因为 WeakSet 中已经不存在 window 对象
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakset.prototype.delete', 'WeakSet.prototype.delete')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakset.prototype.delete', 'WeakSet.prototype.delete')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatGeckoDesktop(34)}}{{CompatNo}}23{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{ CompatGeckoMobile(34) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakset/has/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakset/has/index.html new file mode 100644 index 0000000000..7a06b243e3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakset/has/index.html @@ -0,0 +1,118 @@ +--- +title: WeakSet.prototype.has() +slug: Web/JavaScript/Reference/Global_Objects/WeakSet/has +translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet/has +--- +
{{JSRef}}
+ +

has() 方法根据 WeakSet 是否存在相应对象返回布尔值。

+ +

语法

+ +
ws.has(value);
+ +

参数

+ +
+
value
+
必须。 测试 WeakSet 中是否存在该对象。
+
+ +

返回值

+ +
+
Boolean
+
如果 WeakSet 对象中存在指定的元素,返回 true;否则返回 false。
+
+ +

示例

+ +

使用 has 方法

+ +
var ws = new WeakSet();
+var obj = {};
+ws.add(window);
+
+mySet.has(window);  // 返回 true
+mySet.has(obj);     // 返回 false
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakset.prototype.has', 'WeakSet.prototype.has')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakset.prototype.has', 'WeakSet.prototype.has')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatGeckoDesktop(34)}}{{CompatNo}}23{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{ CompatGeckoMobile(34) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakset/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakset/index.html new file mode 100644 index 0000000000..389a55f5e1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakset/index.html @@ -0,0 +1,148 @@ +--- +title: WeakSet +slug: Web/JavaScript/Reference/Global_Objects/WeakSet +tags: + - WeakSet +translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet +--- +
{{JSRef}}
+ +
+ +

WeakSet 对象允许你将弱保持对象存储在一个集合中。

+ +

语法

+ +
 new WeakSet([iterable]);
+ +

参数

+ +
+
iterable
+
如果传入一个可迭代对象作为参数, 则该对象的所有迭代值都会被自动添加进生成的 WeakSet 对象中。null 被认为是 undefined。
+
+ +

示例

+ +

使用 WeakSet对象

+ +
var ws = new WeakSet();
+var foo = {};
+var bar = {};
+
+ws.add(foo);
+ws.add(bar);
+
+ws.has(foo);    // true
+ws.has(bar);   // true
+
+ws.delete(foo); // 从set中删除 foo 对象
+ws.has(foo);    // false, foo 对象已经被删除了
+ws.has(bar);    // true, bar 依然存在
+ +

注意, foo  !==  bar。 尽管它们是相似的对象,但是它们不是同一个对象。因此,它们都可以被加入到set中。

+ +

描述

+ +

WeakSet 对象是一些对象值的集合, 并且其中的每个对象值都只能出现一次。在WeakSet的集合中是唯一的

+ +

它和 {{jsxref("Set")}} 对象的区别有两点:

+ + + +

检测循环引用

+ +

递归调用自身的函数需要一种通过跟踪哪些对象已被处理,来应对循环数据结构的方法。

+ +

为此,WeakSet非常适合处理这种情况:

+ +
// 对 传入的subject对象 内部存储的所有内容执行回调
+function execRecursively(fn, subject, _refs = null){
+	if(!_refs)
+		_refs = new WeakSet();
+
+	// 避免无限递归
+	if(_refs.has(subject))
+		return;
+
+	fn(subject);
+	if("object" === typeof subject){
+		_refs.add(subject);
+		for(let key in subject)
+			execRecursively(fn, subject[key], _refs);
+	}
+}
+
+const foo = {
+	foo: "Foo",
+	bar: {
+		bar: "Bar"
+	}
+};
+
+foo.bar.baz = foo; // 循环引用!
+execRecursively(obj => console.log(obj), foo);
+ +

在此,在第一次运行时创建WeakSet,并将其与每个后续函数调用一起传递(使用内部参数_refs)。 对象的数量或它们的遍历顺序无关紧要,因此,WeakSet比{{jsxref("Set")}}更适合(和执行)跟踪对象引用,尤其是在涉及大量对象时。

+ +

属性

+ +
+
WeakSet.length
+
length 属性的值为 0.
+
{{jsxref("WeakSet.prototype")}}
+
表示WeakSet构造函数的原型。 允许向所有WeakSet对象添加属性。
+
+ +

WeakSet 实例

+ +

所有 WeakSet 实例都继承自 {{jsxref("WeakSet.prototype")}}.

+ +

属性

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/WeakSet/prototype','Properties')}}

+ +

方法

+ +

{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/WeakSet/prototype','Methods')}}

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范链接规范状态备注
{{SpecName('ES2015', '#sec-weakset-objects', 'WeakSet')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakset-objects', 'WeakSet')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.WeakSet")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakset/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakset/prototype/index.html new file mode 100644 index 0000000000..3f323d5fe2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/weakset/prototype/index.html @@ -0,0 +1,114 @@ +--- +title: WeakSet.prototype +slug: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet +--- +
{{JSRef("Global_Objects", "WeakSet")}}
+ +

Summary

+ +

The WeakSet.prototype property represents the prototype for the {{jsxref("WeakSet")}} constructor.

+ +
{{js_property_attributes(0,0,0)}}
+ +

Description

+ +

{{jsxref("WeakSet")}} instances inherit from {{jsxref("WeakSet.prototype")}}. You can use the constructor's prototype object to add properties or methods to all WeakSet instances.

+ +

Properties

+ +
+
WeakSet.prototype.constructor
+
返回构造函数即 {{jsxref("WeakSet")}} 本身.
+
+ +

Methods

+ +
+
{{jsxref("WeakSet.add", "WeakSet.prototype.add(value)")}}
+
 在该 WeakSet 对象中添加一个新元素 value.
+
{{jsxref("WeakSet.delete", "WeakSet.prototype.delete(value)")}}
+
该 WeakSet 对象中删除 value 这个元素, 之后 WeakSet.prototype.has(value) 方法便会返回 false.
+
{{jsxref("WeakSet.has", "WeakSet.prototype.has(value)")}}
+
返回一个布尔值,  表示给定的值 value 是否存在于这个 WeakSet 中.
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakset.prototype', 'WeakSet.prototype')}}{{Spec2('ES6')}}Initial definition.
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatNo() }} {{bug(792439)}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }} {{bug(792439)}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

Chrome-specific notes

+ + + +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/compile/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/compile/index.html new file mode 100644 index 0000000000..6489b54a09 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/compile/index.html @@ -0,0 +1,101 @@ +--- +title: WebAssembly.compile() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/compile +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/compile +--- +
{{JSRef}} {{SeeCompatTable}}
+ +

WebAssembly.compile() 方法编译WebAssembly二进制代码到一个{{jsxref("WebAssembly.Module")}} 对象。如果在实例化之前有必要去编译一个模块,那么这个方法是有用的(否则,将会使用{{jsxref("WebAssembly.instantiate()")}} 方法)

+ +

语法

+ +
Promise<WebAssembly.Module> WebAssembly.compile(bufferSource);
+ +

参数

+ +
+
bufferSource
+
一个包含你想编译的wasm模块二进制代码的 typed array(类型数组) or ArrayBuffer(数组缓冲区)
+
+ +

返回值

+ +

一个解析为 {{jsxref("WebAssembly.Module")}} 的Promise 对象。

+ +

异常

+ + + +

例子

+ +

下面的例子 (查看GitHub上的 index-compile.html 例子, 并且也能 查看运行效果) 使用 compile() 方法编译加载进来的 simple.wasm 二进制代码并且使用 postMessage() 发送给一个 worker

+ +
var worker = new Worker("wasm_worker.js");
+
+fetch('simple.wasm').then(response =>
+  response.arrayBuffer()
+).then(bytes =>
+  WebAssembly.compile(bytes)
+).then(mod =>
+  worker.postMessage(mod)
+);
+ +

在线程中 (查看 wasm_worker.js) 我们定义了一个导入对象共模块使用,然后设置了一个事件处理函数来接收主线程发送过来的模块。当模块被接收之后,我们使用{{jsxref("WebAssembly.Instantiate()")}} 方法创建了一个实例,调用从它里面导出的一个方法,接下来展示了我们可以用 {{jsxref("WebAssembly.Module/exports", "WebAssembly.Module.exports")}} 属性来调用模块上返回的可用信息。

+ +
var importObject = {
+  imports: {
+    imported_func: function(arg) {
+      console.log(arg);
+    }
+  }
+};
+
+onmessage = function(e) {
+  console.log('module received from main thread');
+  var mod = e.data;
+
+  WebAssembly.instantiate(mod, importObject).then(function(instance) {
+    instance.exports.exported_func();
+  });
+
+  var exports = WebAssembly.Module.exports(mod);
+  console.log(exports[0]);
+};
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('WebAssembly JS', '#webassemblycompile', 'compile()')}}{{Spec2('WebAssembly JS')}}Initial draft definition.
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.compile")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/compileerror/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/compileerror/index.html new file mode 100644 index 0000000000..179b8589a2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/compileerror/index.html @@ -0,0 +1,114 @@ +--- +title: WebAssembly.CompileError() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError +--- +
{{JSRef}}
+ +

WebAssembly.CompileError()构造函数创建一个新的WebAssembly CompileError对象,该对象表示WebAssembly解码或验证期间的错误。

+ +

语法

+ +
new WebAssembly.CompileError(message, fileName, lineNumber)
+ +

参数

+ +
+
message {{optional_inline}}
+
有可读性的错误描述。
+
fileName {{optional_inline}}{{non-standard_inline}}
+
包含导致异常的代码的文件名。
+
lineNumber {{optional_inline}}{{non-standard_inline}}
+
导致异常的代码的行号。
+
+ +

属性

+ +

CompileError构造函数没有一些它特有的属性,但是,它确实通过原型链继承了某些属性。

+ +
+
WebAssembly.CompileError.prototype.constructor
+
创建示例原型的特定函数。
+
{{jsxref("Error.prototype.message", "WebAssembly.CompileError.prototype.message")}}
+
错误信息。 尽管ECMA-262指定{{jsxref("URIError")}}应提供自己的message属性,但在SpiderMonkey中,它继承了 {{jsxref("Error.prototype.message")}}。
+
{{jsxref("Error.prototype.name", "WebAssembly.CompileError.prototype.name")}}
+
错误名称。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.fileName", "WebAssembly.CompileError.prototype.fileName")}}
+
报出错误的文件名。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.lineNumber", "WebAssembly.CompileError.prototype.lineNumber")}}
+
报出错误的代码所在文件中的行数。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.columnNumber", "WebAssembly.CompileError.prototype.columnNumber")}}
+
报出错误的代码所在文件中的列数。继承自 {{jsxref("Error")}}。
+
{{jsxref("Error.prototype.stack", "WebAssembly.CompileError.prototype.stack")}}
+
堆栈跟踪。 继承自{{jsxref("Error")}}。
+
+ +

方法

+ +

CompileError构造函数不包含自己的方法,但是,它确实通过原型链继承了一些方法。

+ +
+
{{jsxref("Error.prototype.toSource", "WebAssembly.CompileError.prototype.toSource()")}}
+
返回可能导致相同错误的代码。 继承自{{jsxref("Error")}}。
+
{{jsxref("Error.prototype.toString", "WebAssembly.CompileError.prototype.toString()")}}
+
返回表示代表指定的Error对象的字符串。从 {{jsxref("Error")}}继承。
+
+ +

示例

+ +

以下代码段创建一个新的CompileError实例,并将其详细信息记录到控制台:

+ +
try {
+  throw new WebAssembly.CompileError('Hello', 'someFile', 10);
+} catch (e) {
+  console.log(e instanceof CompileError); // true
+  console.log(e.message);                 // "Hello"
+  console.log(e.name);                    // "CompileError"
+  console.log(e.fileName);                // "someFile"
+  console.log(e.lineNumber);              // 10
+  console.log(e.columnNumber);            // 0
+  console.log(e.stack);                   // 返回代码运行的位置
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('WebAssembly JS', '#constructor-properties-of-the-webassembly-object', 'WebAssembly constructors')}}{{Spec2('WebAssembly JS')}}Initial WebAssembly draft definition.
{{SpecName('ESDraft', '#sec-native-error-types-used-in-this-standard', 'NativeError')}}{{Spec2('ESDraft')}}Definition of standard NativeError types.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.CompileError")}}

+
+ +

参见

+ + + +
+
diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/compilestreaming/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/compilestreaming/index.html new file mode 100644 index 0000000000..f36e646699 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/compilestreaming/index.html @@ -0,0 +1,77 @@ +--- +title: WebAssembly.compileStreaming() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming +--- +
{{JSRef}}
+ +

WebAssembly.compileStreaming() 方法用来从一个流式源中直接编译一个 {{jsxref("WebAssembly.Module")}}。当模块需要在被实例化前被编译时,这个方法会很有用。如果要从流式源实例化一个模块应采用 {{jsxref("WebAssembly.instantiateStreaming()")}} 方法。

+ +

语法

+ +
Promise<WebAssembly.Module> WebAssembly.compileStreaming(source);
+ +

参数

+ +
+
source
+
一个 {{domxref("Response")}} 对象或一个会履行(fulfill)它的 promise,用来表示你想编译的 .wasm 模块的流式源。
+
+ +

返回值

+ +

一个会被解决(resolve)为编译后的 {{jsxref("WebAssembly.Module")}} 对象的 Promise

+ +

异常

+ + + +

例子

+ +

下面的例子(在 GitHub 上查看我们的 compile-streaming.html 示例或者直接在线预览)直接从流式源传输一个 .wasm 模块然后将其编译为一个 {{jsxref("WebAssembly.Module")}} 对象。因为 compileStreaming() 方法可以接受一个结果为  {{domxref("Response")}} 对象的 promise,因此你可以直接用 {{domxref("WindowOrWorkerGlobalScope.fetch()")}} 的调用结果来调用该方法。

+ +
var importObject = { imports: { imported_func: arg => console.log(arg) } };
+
+WebAssembly.compileStreaming(fetch('simple.wasm'))
+.then(module => WebAssembly.instantiate(module, importObject))
+.then(instance => instance.exports.exported_func());
+ +

得到的 module 实例接下来通过 {{jsxref("WebAssembly.instantiate()")}} 方法被实例化了,然后调用模块导出的函数。

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('WebAssembly Embedding', '#webassemblycompilestreaming', 'compileStreaming()')}}{{Spec2('WebAssembly Embedding')}}Initial draft definition.
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.compileStreaming")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/global/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/global/index.html new file mode 100644 index 0000000000..3366032120 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/global/index.html @@ -0,0 +1,107 @@ +--- +title: WebAssembly.Global +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/Global +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/Global +--- +
{{JSRef}}
+ +

WebAssembly.Global 对象表示一个全局变量实例, 可以被JavaScript 和importable/exportable 访问 ,跨越一个或多个{{jsxref("WebAssembly.Module")}} 实例. 他允许被多个modules动态连接.

+ +

构造函数语法

+ +

WebAssembly.Global()

+ +

     创建一个新的全局对象。

+ +

Global 实例

+ +

所有的 Global 实例 继承自 Global() 构造函数 prototype object — 修改会影响 所有 Global 实例.

+ +

实例属性

+ +
+
Global.prototype.constructor
+
返回创建对象实例的函数. 缺省为构造函数为 {{jsxref("WebAssembly.Global()")}}
+
Global.prototype[@@toStringTag]
+
属性 @@toStringTag 初始值为字符串 "WebAssembly.Global".
+
Global.prototype.value
+
全局变量包含的值 — 可以直接用于设置和获取全局变量的值.
+
+ +

实例方法

+ +
+
Global.prototype.valueOf()
+
旧式的方法,返回全局变量包含的值.
+
+ +

例子

+ +

创建 Global 实例 

+ +

以下例子展示了使用 WebAssembly.Global() 构造函数创建一个新的实例. 它定义为可修饰的 类型为i32 , 值为 0.

+ +

global的值发生改变, 首先设置Global.value 为42, 然后使用导出函数 incGlobal() 增加为43. 导出函数在 global.wasm 模块中(它将参数的值加一并返回).

+ +
const output = document.getElementById('output');
+
+function assertEq(msg, got, expected) {
+    output.innerHTML += `Testing ${msg}: `;
+    if (got !== expected)
+        output.innerHTML += `FAIL!<br>Got: ${got}<br>Expected: ${expected}<br>`;
+    else
+        output.innerHTML += `SUCCESS! Got: ${got}<br>`;
+}
+
+assertEq("WebAssembly.Global exists", typeof WebAssembly.Global, "function");
+
+const global = new WebAssembly.Global({value:'i32', mutable:true}, 0);
+
+WebAssembly.instantiateStreaming(fetch('global.wasm'), { js: { global } })
+.then(({instance}) => {
+    assertEq("getting initial value from wasm", instance.exports.getGlobal(), 0);
+    global.value = 42;
+    assertEq("getting JS-updated value from wasm", instance.exports.getGlobal(), 42);
+    instance.exports.incGlobal();
+    assertEq("getting wasm-updated value from JS", global.value, 43);
+});
+ +
+

注意: 你可以在running live on GitHub 查看例子; 也可以访问source code.

+
+ +

规格

+ + + + + + + + + + + + + + + + +
规格状态解释
{{SpecName('WebAssembly JS', '#globals', 'WebAssembly.Global()')}}{{Spec2('WebAssembly JS')}}Initial draft definition.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.Global")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/index.html new file mode 100644 index 0000000000..66f14793af --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/index.html @@ -0,0 +1,106 @@ +--- +title: WebAssembly +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly +tags: + - API + - JavaScript + - WebAssembly +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly +--- +
{{JSRef}}
+ +

WebAssemblyJavaScript 对象是所有 WebAssembly 相关功能的命名空间。

+ +

和大多数全局对象不一样,WebAssembly不是一个构造函数(它不是一个函数对象)。它类似于 {{jsxref("Math")}} 对象或者 {{jsxref("Intl")}} 对象,Math 对象也是一个命名空间对象,用于保存数学常量和函数;Intl则是用于国际化和其他语言相关函数的命名空间对象。

+ +

描述

+ +

WebAssembly对象主要用于:

+ + + +

方法

+ +
+
{{jsxref("WebAssembly.instantiate()")}}
+
用于编译和实例化 WebAssembly 代码的主 API,返回一个 Module 和它的第一个Instance实例。
+
{{jsxref("WebAssembly.instantiateStreaming()")}}
+
直接从流式底层源编译和实例化WebAssembly模块,同时返回Module及其第一个Instance实例。
+
{{jsxref("WebAssembly.compile()")}}
+
把 WebAssembly 二进制代码编译为一个 {{jsxref("WebAssembly.Module")}} ,不进行实例化。
+
{{jsxref("WebAssembly.compileStreaming()")}}
+
直接从流式底层源代码编译{{jsxref("WebAssembly.Module")}} ,将实例化作为一个单独的步骤。
+
{{jsxref("WebAssembly.validate()")}}
+
校验 WebAssembly 二进制代码的类型数组是否合法,合法则返回 true ,否则返回 false 。
+
+ +

构造器

+ +
+
{{jsxref("WebAssembly.Global()")}}
+
创建一个新的WebAssembly Global 全局对象.
+
{{jsxref("WebAssembly.Module()")}}
+
创建一个新的WebAssembly Module模块对象。
+
{{jsxref("WebAssembly.Instance()")}}
+
创建一个新的WebAssembly Instance实例对象。
+
{{jsxref("WebAssembly.Memory()")}}
+
创建一个新的WebAssembly Memory内存对象。
+
{{jsxref("WebAssembly.Table()")}}
+
创建一个新的WebAssembly Table表格对象。
+
{{jsxref("WebAssembly.CompileError()")}}
+
创建一个新的WebAssembly CompileError编译错误对象。
+
{{jsxref("WebAssembly.LinkError()")}}
+
创建一个新的WebAssembly LinkError链接错误对象。
+
{{jsxref("WebAssembly.RuntimeError()")}}
+
创建一个新的WebAssembly RuntimeError运行时错误对象。
+
+ +

示例

+ +

下面的示例(请参见GitHub上的Instantiate-streaming.html演示,并查看在线演示)直接从流式底层源传输.wasm模块,然后对其进行编译和实例化,并通过ResultObject实现promise。 由于instantiateStreaming()函数接受对 {{domxref("Response")}} 对象的promise,因此您可以直接向其传递{{domxref("WindowOrWorkerGlobalScope.fetch()")}}调用,然后它将把返回的response传递给随后的函数。

+ +
var importObject = { imports: { imported_func: arg => console.log(arg) } };
+
+WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject)
+.then(obj => obj.instance.exports.exported_func())
+ +

返回的ResultObject实例的成员可以被随后访问到,可以调用实例中被导出的方法。

+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('WebAssembly JS', '#the-webassembly-object', 'WebAssembly')}}{{Spec2('WebAssembly JS')}}初始草案定义
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly")}}

+ +

参见

+ + +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/instance/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/instance/index.html new file mode 100644 index 0000000000..d9fdee81e1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/instance/index.html @@ -0,0 +1,89 @@ +--- +title: WebAssembly.Instance +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance +tags: + - API + - Experimental + - JavaScript + - Reference + - WebAssembly +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance +--- +
{{JSRef}} {{SeeCompatTable}}
+ +

  WebAssembly.Instance 对象本身是有状态的,是 WebAssembly.Module 的一个可执行实例。  实例包含所有的 WebAssembly 导出函数 ,允许从JavaScript 调用 WebAssembly 代码。

+ +

WebAssembly.Instance() 构造函数以同步方式实例化一个{{jsxref("WebAssembly.Module")}} 对象。 然而, 通常获取实例的方法是通过异步函数{{jsxref("WebAssembly.instantiate()")}} .

+ +

构造函数

+ +
+

重要: 由于大型模块的实例化代价极高, 开发人员应只在必须同步实例化的时候,才使用Instance();绝大多数情况应该使用异步方法{{jsxref("WebAssembly.instantiate()")}} .

+
+ +
var myInstance = new WebAssembly.Instance(module, importObject);
+ +

参数

+ +
+
module
+
要被实例化的 WebAssembly.Module 对象.
+
importObject {{optional_inline}}
+
一个包含值的对象,导入到新创建的 实例, 比如函数或 WebAssembly.Memory 对象. There must be one matching property for each declared import of module 否则抛出 WebAssembly.LinkError 异常.
+
+ +

实例化

+ +

所有的 Instance 实例继承自Instance() 属性对象— 修改它会影响所有的Instance 实例.

+ +

实例属性

+ +
+
{{jsxref("WebAssembly/Instance/exports", "Instance.prototype.exports")}}
+
返回一个包含此 WebAssembly 模块实例所导出的全部成员的 JS 对象,以便 JavaScript 访问和使用这些成员,这个对象是只读的。
+
+
+ + + +

规格

+ + + + + + + + + + + + + + + + +
规格状态描述
{{SpecName('WebAssembly JS', '#webassemblyinstance-objects', 'Instance')}}{{Spec2('WebAssembly JS')}}Initial draft definition.
+ +

浏览器兼容性

+ + + +
{{Compat("javascript.builtins.WebAssembly.Instance")}}
+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/instantiate/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/instantiate/index.html new file mode 100644 index 0000000000..5567c99432 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/instantiate/index.html @@ -0,0 +1,175 @@ +--- +title: WebAssembly.instantiate() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate +--- +
{{JSRef}}
+ +

WebAssembly.instantiate() 允许你编译和实例化 WebAssembly 代码。这个方法有两个重载方式:

+ + + +
+

重要: 此方法不是获取(fetch)和实例化wasm模块的最具效率方法。 如果可能的话,您应该改用较新的{{jsxref("WebAssembly.instantiateStreaming()")}}方法,该方法直接从原始字节码中直接获取,编译和实例化模块,因此不需要转换为{{jsxref("ArrayBuffer")}}。

+
+ +

语法

+ +

主重载方式 — 使用wasm二进制代码

+ +
Promise<ResultObject> WebAssembly.instantiate(bufferSource, importObject);
+
+ +

参数

+ +
+
bufferSource
+
一个包含你想编译的wasm模块二进制代码的 typed array(类型数组) or ArrayBuffer(数组缓冲区)
+
importObject {{optional_inline}}
+
一个将被导入到新创建实例中的对象,它包含的值有函数、{{jsxref("WebAssembly.Memory")}} 对象等等。编译的模块中,对于每一个导入的值都要有一个与其匹配的属性与之相对应,否则将会抛出 WebAssembly.LinkError
+
+ +

返回值

+ +

解析为包含两个字段的 ResultObject 的一个 Promise:

+ + + +

异常

+ + + +

第二种重载 — 使用模块对象

+ +
Promise<WebAssembly.Instance> WebAssembly.instantiate(module, importObject);
+
+ +

参数

+ +
+
module
+
将被实例化的 {{jsxref("WebAssembly.Module")}} 对象。
+
importObject {{optional_inline}}
+
一个将被导入到新创建实例中的对象,它包含的值有函数、{{jsxref("WebAssembly.Memory")}} 对象等等。编译的模块中,对于每一个导入的值都要有一个与其匹配的属性与之相对应,否则将会抛出{{jsxref("WebAssembly.LinkError")}} 。
+
+ +

返回值

+ +

一个解析为 {{jsxref("WebAssembly.Instance")}} 的Promise 对象。

+ +

异常

+ + + +

例子

+ +

提示: 在大多数情况下,您可能需要使用{{jsxref("WebAssembly.instantiateStreaming()")}},因为它比instantiate()更具效率。

+ +

第一种重载例子

+ +

使用 fetch 获取一些 WebAssembly 二进制代码后,我们使用 {{jsxref("WebAssembly.instantiate()")}}  方法编译并实例化模块,在此过程中,导入了一个 Javascript 方法在 WebAssembly 模块中, 接下来我们使用Instance 导出的Exported WebAssembly 方法。

+ +
var importObject = {
+  imports: {
+    imported_func: function(arg) {
+      console.log(arg);
+    }
+  },
+  env: {
+    abort: () => {},
+  },
+};
+
+/* 2019-08-03:importObject必须存在env对象以及env对象的abort方法 */
+
+fetch('simple.wasm').then(response =>
+  response.arrayBuffer()
+).then(bytes =>
+  WebAssembly.instantiate(bytes, importObject)
+).then(result =>
+  result.instance.exports
+);
+ +
+

: 查看GitHub(在线实例)的 index.html 中一个相似的例子,使用了我们的fetchAndInstantiate()库函数

+
+ +

第二种重载例子

+ +

下面的例子(查看我们GitHub的 index-compile.html 例子,可在线演示)使用 compile() 方法编译了 simple.wasm 字节码,然后通过 postMessage() 发送给一个线程 worker

+ +
var worker = new Worker("wasm_worker.js");
+
+fetch('simple.wasm').then(response =>
+  response.arrayBuffer()
+).then(bytes =>
+  WebAssembly.compile(bytes)
+).then(mod =>
+  worker.postMessage(mod)
+);
+ +

在线程中 (查看 wasm_worker.js) 我们定义了一个导入对象供模块使用,然后设置了一个事件处理函数来接收主线程发来的模块。当模块被接收到后,我们使用{{jsxref("WebAssembly.instantiate()")}} 方法创建一个实例并且调用它从内部导出的函数。

+ +
var importObject = {
+  imports: {
+    imported_func: function(arg) {
+      console.log(arg);
+    }
+  }
+};
+
+onmessage = function(e) {
+  console.log('module received from main thread');
+  var mod = e.data;
+
+  WebAssembly.instantiate(mod, importObject).then(function(instance) {
+    instance.exports.exported_func();
+  });
+};
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('WebAssembly JS', '#webassemblyinstantiate', 'instantiate()')}}{{Spec2('WebAssembly JS')}}Initial draft definition.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.instantiate")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/instantiatestreaming/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/instantiatestreaming/index.html new file mode 100644 index 0000000000..f6698d9862 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/instantiatestreaming/index.html @@ -0,0 +1,85 @@ +--- +title: WebAssembly.instantiateStreaming() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming +--- +
{{JSRef}}
+ +

WebAssembly.instantiateStreaming() 方法直接从流式底层源编译和实例化WebAssembly模块。这是加载wasm代码一种非常有效的优化方式。

+ +

Syntax

+ +
Promise<ResultObject> WebAssembly.instantiateStreaming(source, importObject);
+ +

Parameters

+ +
+
source
+
一个{{domxref("Response")}}对象 或 一个可以履行(fulfill)一个(Response)的 {{jsxref("Promise")}},表示你想要传输、编译和实例化的 .wasm 模块基础源。
+
importObject {{optional_inline}}
+
包含一些想要导入到新创建Instance中值的对象,例如方法 或  {{jsxref("WebAssembly.Memory")}} 对象。每个已编译模块的声明导入必须有一个匹配属性,否则抛出 WebAssembly.LinkError 异常。
+
+ +

Return value

+ +

一个 Promise ,通过resolve返回一个包含两个属性的 ResultObject :

+ + + +

Exceptions

+ + + +

Examples

+ +

下面的示例 (在GitHub上查看 instantiate-streaming.html 示例, 并且也可 view it live ) 直接从基础源传输一个 .wasm 模块,然后进行编译和实例化, Promise 履行后返回一个 ResultObject. 因为 instantiateStreaming() 方法允许履行后返回{{domxref("Response")}}对象的Promise,你可以直接传递一个 {{domxref("WindowOrWorkerGlobalScope.fetch()")}} 请求,它会在履行后将response传递给方法.

+ +
var importObject = { imports: { imported_func: arg => console.log(arg) } };
+
+WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject)
+.then(obj => obj.instance.exports.exported_func());
+ +

然后访问ResultObject的实例成员,并调用包含的公开函数。

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('WebAssembly Embedding', '#webassemblyinstantiatestreaming', 'instantiateStreaming()')}}{{Spec2('WebAssembly Embedding')}}Initial draft definition.
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.instantiateStreaming")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/memory/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/memory/index.html new file mode 100644 index 0000000000..1d559210a4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/memory/index.html @@ -0,0 +1,112 @@ +--- +title: WebAssembly.Memory() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory +--- +
{{JSRef}}
+ +

WebAssembly.Memory() 构造函数创建一个新的 Memory 对象。该对象的 {{jsxref("WebAssembly/Memory/buffer","buffer")}} 属性是一个可调整大小的 ArrayBuffer ,其内存储的是 WebAssembly 实例 所访问内存的原始字节码。

+ +

从 JavaScript 或 WebAssembly 中所创建的内存,可以由 JavaScript 或 WebAssembly 来访问及更改。

+ +

语法

+ +
var myMemory = new WebAssembly.Memory(memoryDescriptor);
+ +

参数

+ +
+
memoryDescriptor
+
一个可包含以下成员的对象: +
+
initial
+
WebAssembly 内存的初始大小,以 WebAssembly 页面为单位。
+
maximum {{optional_inline}}
+
以 WebAssembly 页面为单位,可允许 WebAssembly 内存的 最大值。当存在此属性时,此参数用于提示引擎预先保留内存。但是,引擎可能会忽略或限制此预留请求。通常情况下大多数 WebAssembly 模块不需要设置 最大值
+
+
+
+ +
+

注意: A WebAssembly 页面的大小为一个常量 65,536 字节,即64KB。

+
+ +

异常

+ + + +

Memory 实例

+ +

所有 Memory 实例都继承自 Memory() 构造函数的 原型对象 — 这个原型可被修改并影响到所有的 Memory 实例。

+ +

实例属性

+ +
+
Memory.prototype.constructor
+
返回创建此对象实例的函数。默认情况下,它是 {{jsxref("WebAssembly.Memory()")}} 构造函数。
+
{{jsxref("WebAssembly/Memory/buffer","Memory.prototype.buffer")}}
+
一个访问器,用于返回内存中包含的缓冲区。
+
+ +

实例方法

+ +
+
{{jsxref("WebAssembly/Memory/grow","Memory.prototype.grow()")}}
+
通过指定 WebAssembly 页面数量来增加内存实例的大小。(每个页面大小为64KB)
+
+ +

示例

+ +

有两种方法可以获得 WebAssembly.Memory 对象。第一种方法是由 JavaScript 来创建。以下示例创建了一个新的 WebAssembly 内存实例,初始大小为 10页(640KB),最大值设置为 100页(6.4MB)。

+ +
var memory = new WebAssembly.Memory({initial:10, maximum:100});
+ +

获取 WebAssembly.Memory 对象的第二种方法是从 WebAssembly 模块中导出。以下示例 (详见GitHub页面 memory.html ,也可以 用浏览器运行查看) 使用 {{jsxref("WebAssembly.instantiateStreaming()")}} 方法实例化已加载的 memory.wasm 字节代码,同时导入上面一行中创建的内存。用它来存储一些值,然后导出一个函数并用它来对一些值进行求和操作。

+ +
WebAssembly.instantiateStreaming(fetch('memory.wasm'), { js: { mem: memory } })
+.then(obj => {
+  var i32 = new Uint32Array(memory.buffer);
+  for (var i = 0; i < 10; i++) {
+    i32[i] = i;
+  }
+  var sum = obj.instance.exports.accumulate(0, 10);
+  console.log(sum);
+});
+ +

标准规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('WebAssembly JS', '#webassemblymemory-objects', 'Memory')}}{{Spec2('WebAssembly JS')}}初步定义草案
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.Memory")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/module/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/module/index.html new file mode 100644 index 0000000000..c328e5f3ba --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/module/index.html @@ -0,0 +1,87 @@ +--- +title: WebAssembly.Module +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/Module +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/Module +--- +
{{JSRef}}
+ +
WebAssembly.Module 对象包含已经由浏览器编译的无状态 WebAssembly 代码,可以高效地与 Workers 共享缓存在 IndexedDB 中,和多次实例化。
+ +
 
+ +
WebAssembly.Module() 构造函数可以用来同步编译给定的 WebAssembly 二进制代码。不过,获取 Module 对象的主要方法是通过异步编译函数,如 {{jsxref("WebAssembly.compile()")}},或者是通过 IndexedDB 读取 Module 对象.
+ +
 
+ +

构造函数语法

+ +
+

重要提示:由于大型模块的编译可能很消耗资源,开发人员只有在绝对需要同步编译时,才使用 Module() 构造函数;其他情况下,应该使用异步 {{jsxref("WebAssembly.compile()")}} 方法。

+
+ +
var myModule = new WebAssembly.Module(bufferSource);
+ +

参数

+ +
+
bufferSource
+
一个 类型化数组 或 ArrayBuffer,包含要编译的 .wasm 模块的二进制代码。
+
+ +

Module 构造函数的方法属性

+ +
+
{{jsxref("Global_Objects/WebAssembly/Module/customSections", "WebAssembly.Module.customSections()")}}
+
给定 Module 对象和字符串,通过该字符串,返回 Module 对象中所有自定义部分的内容的副本。
+
{{jsxref("Global_Objects/WebAssembly/Module/exports", "WebAssembly.Module.exports()")}}
+
给定 Module 对象,返回一个数组,内容是所有已声明的接口的描述。
+
{{jsxref("Global_Objects/WebAssembly/Module/imports", "WebAssembly.Module.imports()")}}
+
给定 Module 对象,返回一个数组,内容是所有已声明的引用的描述。
+
+ +

Module 实例

+ +

所有 Module 实例继承自 Module() 构造函数的原型对象 —— 修改它会影响所有 Module 实例。

+ +

实例属性

+ +

{{page('/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/prototype', 'Properties')}}

+ +

实例方法

+ +

Module 实例没有自己的默认方法。

+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('WebAssembly JS', '#webassemblymodule-objects', 'WebAssembly.Module()')}}{{Spec2('WebAssembly JS')}}定义初稿
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.Module")}}

+
+ +

另请查阅

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/runtimeerror/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/runtimeerror/index.html new file mode 100644 index 0000000000..3962917a9e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/runtimeerror/index.html @@ -0,0 +1,111 @@ +--- +title: WebAssembly.RuntimeError() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/RuntimeError +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/RuntimeError +--- +
{{JSRef}}
+ +

WebAssembly.RuntimeError()构造函数创建一个新的WebAssembly RuntimeError对象---一个每当WebAssembly陷入指定陷阱时将抛出的类型。

+ +

语法

+ +
new WebAssembly.RuntimeError(message, fileName, lineNumber)
+ +

参数

+ +
+
message {{optional_inline}}
+
有可读性的错误信息。
+
fileName {{optional_inline}}{{non-standard_inline}}
+
包含导致异常的代码的文件名。
+
lineNumber {{optional_inline}}{{non-standard_inline}}
+
导致异常的代码的行号。
+
+ +

属性

+ +

RuntimeError构造函数不包含其自身特有的属性,但是,它确实通过原型链继承了某些属性。

+ +
+
WebAssembly.RuntimeError.prototype.constructor
+
创建示例原型的特定函数。
+
{{jsxref("Error.prototype.message", "WebAssembly.RuntimeError.prototype.message")}}
+
错误信息。 尽管ECMA-262指定{{jsxref("URIError")}}应提供自己的message属性,但在SpiderMonkey中,它继承了{{jsxref("Error.prototype.message")}}。
+
{{jsxref("Error.prototype.name", "WebAssembly.RuntimeError.prototype.name")}}
+
错误名称。继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.fileName", "WebAssembly.RuntimeError.prototype.fileName")}}
+
报出错误的文件路径。继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.lineNumber", "WebAssembly.RuntimeError.prototype.lineNumber")}}
+
报出错误的代码所在文件中的行数。继承自{{jsxref("Error")}}.
+
{{jsxref("Error.prototype.columnNumber", "WebAssembly.RuntimeError.prototype.columnNumber")}}
+
报出错误的代码所在文件中的列数。继承自 {{jsxref("Error")}}.
+
{{jsxref("Error.prototype.stack", "WebAssembly.RuntimeError.prototype.stack")}}
+
堆栈跟踪。 继承自 {{jsxref("Error")}}.
+
+ +

方法

+ +

RuntimeError构造函数不包含自己的方法,但是,它确实通过原型链继承了一些方法。

+ +
+
{{jsxref("Error.prototype.toSource", "WebAssembly.RuntimeError.prototype.toSource()")}}
+
返回可能导致相同错误的代码。 继承自{{jsxref("Error")}}.
+
{{jsxref("Error.prototype.toString", "WebAssembly.RuntimeError.prototype.toString()")}}
+
返回表示代表指定的Error对象的字符串。从{{jsxref("Error")}}.
+
+ +

样例

+ +

以下代码段创建了一个新的RuntimeError实例,并将其详细信息记录到控制台:

+ +
try {
+  throw new WebAssembly.RuntimeError('Hello', 'someFile', 10);
+} catch (e) {
+  console.log(e instanceof RuntimeError); // true
+  console.log(e.message);                 // "Hello"
+  console.log(e.name);                    // "RuntimeError"
+  console.log(e.fileName);                // "someFile"
+  console.log(e.lineNumber);              // 10
+  console.log(e.columnNumber);            // 0
+  console.log(e.stack);                   // 返回代码运行的位置
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('WebAssembly JS', '#constructor-properties-of-the-webassembly-object', 'WebAssembly constructors')}}{{Spec2('WebAssembly JS')}}Initial WebAssembly draft definition.
{{SpecName('ESDraft', '#sec-native-error-types-used-in-this-standard', 'NativeError')}}{{Spec2('ESDraft')}}Definition of standard NativeError types.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.RuntimeError")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/table/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/table/index.html new file mode 100644 index 0000000000..a3fbc0a4dc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/table/index.html @@ -0,0 +1,130 @@ +--- +title: WebAssembly.Table() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/Table +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/Table +--- +
{{JSRef}}
+ +

WebAssembly.Table() 构造函数根据给定的大小和元素类型创建一个Table对象。 

+ +

这是一个包装了WebAssemble Table 的Javascript包装对象,具有类数组结构,存储了多个函数引用。在Javascript或者WebAssemble中创建Table 对象可以同时被Javascript或WebAssemble 访问和更改。

+ +
+

Note: Tables 对象目前只能存储函数引用,不过在将来可能会被扩展。

+
+ +

语法

+ +
var myTable = new WebAssembly.Table(tableDescriptor);
+ +

参数

+ +
+
tableDescriptor
+
该对象具有以下属性: +
+
element
+
一个表明储存在该Table中对象的类型。 目前只能是: "anyfunc" (函数)。
+
initial
+
该WebAssembly Table初始大小。
+
maximum {{optional_inline}}
+
该WebAssembly Table允许扩展到的最大大小。
+
+
+
+ +

异常

+ + + +

Table Instance

+ +

所有Table实例都继承自Table()构造函数的原型对象-可以对其进行修改以影响所有Table实例。

+ +

Instance 属性

+ +
+
Table.prototype.constructor
+
返回创建该对象实例的函数。默认情况下,这是{{jsxref("WebAssembly.Table()")}} 的构造函数。
+
{{jsxref("WebAssembly/Table/length","Table.prototype.length")}}
+
返回Table的长度,即元素数。
+
+ +

Instance methods

+ +
+
{{jsxref("WebAssembly/Table/get","Table.prototype.get()")}}
+
Accessor function — gets the element stored at a given index.
+
{{jsxref("WebAssembly/Table/grow","Table.prototype.grow()")}}
+
Increases the size of the Table instance by a specified number of elements.
+
{{jsxref("WebAssembly/Table/set","Table.prototype.set()")}}
+
Sets an element stored at a given index to a given value.
+
+ +

例子

+ +

The following example (see table2.html source code and live version) creates a new WebAssembly Table instance with an initial size of 2 elements. We then print out the table length and contents of the two indexes (retrieved via {{jsxref("WebAssembly/Table/get", "Table.prototype.get()")}} to show that the length is two and both elements are {{jsxref("null")}}.

+ +
var tbl = new WebAssembly.Table({initial:2, element:"anyfunc"});
+console.log(tbl.length);  // "2"
+console.log(tbl.get(0));  // "null"
+console.log(tbl.get(1));  // "null"
+ +

We then create an import object that contains the table:

+ +
var importObj = {
+  js: {
+    tbl:tbl
+  }
+};
+ +

Finally, we load and instantiate a wasm module (table2.wasm) using the {{jsxref("WebAssembly.instantiateStreaming()")}} method.  The table2.wasm module contains two functions (one that returns 42 and another that returns 83) and stores both into elements 0 and 1 of the imported table (see text representation).  So after instantiation, the table still has length 2, but the elements now contain callable Exported WebAssembly Functions which we can call from JS.

+ +
WebAssembly.instantiateStreaming(fetch('table2.wasm'), importObject)
+.then(function(obj) {
+  console.log(tbl.length);
+  console.log(tbl.get(0)());
+  console.log(tbl.get(1)());
+});
+ +

Note how you've got to include a second function invocation operator at the end of the accessor to actually invoke the referenced function and log the value stored inside it (e.g. get(0)() rather than get(0)) .

+ +

This example shows that we're creating and accessing the table from JavaScript, but the same table is visible and callable inside the wasm instance too.

+ +

规范

+ + + + + + + + + + + + + + + + +
规范StatusComment
{{SpecName('WebAssembly JS', '#webassemblytable-objects', 'Table')}}{{Spec2('WebAssembly JS')}}Initial draft definition.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.Table")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/global_objects/webassembly/validate/index.html b/files/zh-cn/web/javascript/reference/global_objects/webassembly/validate/index.html new file mode 100644 index 0000000000..7d44cc216b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/webassembly/validate/index.html @@ -0,0 +1,75 @@ +--- +title: WebAssembly.validate() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/validate +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/validate +--- +
{{JSRef}}
+ +

WebAssembly.validate() 方法用于验证包含 WebAssembly 二进制码的一个 typed array 是否合法,返回 true 如果这些字节能构成一个合法的 wasm 模块,否则返回 false

+ +

语法

+ +
WebAssembly.validate(bufferSource);
+ +

参数

+ +
+
bufferSource
+
一个包含 WebAssembly 二进制码的 typed array 或 ArrayBuffer
+
+ +

返回值

+ +

一个布尔值,用来表示给定的 bufferSource 是合法 wasm 代码(true)或者不是(false)。

+ +

异常

+ +

如果给定的 bufferSource 不是 typed array 或 ArrayBuffer 类型,将会抛出 {{jsxref("TypeError")}} 异常。

+ +

例子

+ +

下面的例子(查看 validate.html 源代码,或者在线预览)通过 fetch 获取了一个 .wasm 模块并将其转换为一个 typed array。接下来用 validate() 方法来验证这个模块是否合法。

+ +
fetch('simple.wasm').then(response =>
+  response.arrayBuffer()
+).then(function(bytes) {
+  var valid = WebAssembly.validate(bytes);
+  console.log("The given bytes are "
+    + (valid ? "" : "not ") + "a valid wasm module");
+});
+
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('WebAssembly JS', '#webassemblyvalidate', 'validate()')}}{{Spec2('WebAssembly JS')}}Initial draft definition.
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.WebAssembly.validate")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/index.html b/files/zh-cn/web/javascript/reference/index.html new file mode 100644 index 0000000000..dd190e13e5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/index.html @@ -0,0 +1,423 @@ +--- +title: JavaScript 参考 +slug: Web/JavaScript/Reference +tags: + - ECMAScript + - JS + - JavaScript + - 参考 +translation_of: Web/JavaScript/Reference +--- +
{{JsSidebar}}
+ +
在 MDN 的 JavaScript 分区中,这一部分被作为 Javascript 的资料库。阅读关于该参考以了解更多。
+ +

内置

+ +

{{JSxRef("Global_Objects", "JavaScript 标准内置对象")}}, 以及他们的方法和属性.

+ + + + + + + + + +

语句

+ +

{{JSxRef("Statements", "语句和声明")}}

+ + + + + +

表达式和运算符

+ +

{{JSxRef("Operators", "表达式和运算符")}}. 

+ +
+ + + + + +
+ +

函数

+ +

本章介绍如何使用 JavaScript函数 来开发应用程序。

+ + + +

附加参考页面

+ + diff --git a/files/zh-cn/web/javascript/reference/iteration_protocols/index.html b/files/zh-cn/web/javascript/reference/iteration_protocols/index.html new file mode 100644 index 0000000000..8f124ba39b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/iteration_protocols/index.html @@ -0,0 +1,390 @@ +--- +title: 迭代协议 +slug: Web/JavaScript/Reference/Iteration_protocols +tags: + - ECMAScript 2015 + - JavaScript + - 可迭代协议 + - 迭代 + - 迭代器 + - 迭代器协议 +translation_of: Web/JavaScript/Reference/Iteration_protocols +--- +
{{jsSidebar("More")}}
+ +

作为 ECMAScript 2015 的一组补充规范,迭代协议并不是新的内置实现或语法,而是协议。这些协议可以被任何遵循某些约定的对象来实现。

+ +

迭代协议具体分为两个协议:可迭代协议迭代器协议

+ +

可迭代协议

+ +

可迭代协议允许 JavaScript 对象定义或定制它们的迭代行为,例如,在一个 {{jsxref("Statements/for...of", "for..of")}} 结构中,哪些值可以被遍历到。一些内置类型同时是内置可迭代对象,并且有默认的迭代行为,比如 {{jsxref("Array")}} 或者 {{jsxref("Map")}},而其他内置类型则不是(比如 {{jsxref("Object")}}))。

+ +

要成为可迭代对象, 一个对象必须实现 @@iterator 方法。这意味着对象(或者它原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 {{jsxref("Symbol.iterator")}} 访问该属性:

+ + + + + + + + + + + + + + +
属性
[Symbol.iterator] +

一个无参数的函数,其返回值为一个符合迭代器协议的对象。

+
+ +

当一个对象需要被迭代的时候(比如被置入一个 {{jsxref("Statements/for...of", "for...of")}} 循环时),首先,会不带参数调用它的 @@iterator 方法,然后使用此方法返回的迭代器获得要迭代的值。

+ +

值得注意的是调用此零个参数函数时,它将作为对可迭代对象的方法进行调用。 因此,在函数内部,this关键字可用于访问可迭代对象的属性,以决定在迭代过程中提供什么。

+ +

此函数可以是普通函数,也可以是生成器函数,以便在调用时返回迭代器对象。 在此生成器函数的内部,可以使用yield提供每个条目。

+ +

迭代器协议

+ +

迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式。当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认返回值。

+ +

只有实现了一个拥有以下语义(semantic)的 next() 方法,一个对象才能成为迭代器:

+ + + + + + + + + + + + +
属性
next +

一个无参数函数,返回一个应当拥有以下两个属性的对象:

+ +
+
done(boolean)
+
+

如果迭代器可以产生序列中的下一个值,则为 false。(这等价于没有指定  done 这个属性。)

+ +

如果迭代器已将序列迭代完毕,则为 true。这种情况下,value 是可选的,如果它依然存在,即为迭代结束之后的默认返回值。

+
+
value
+
迭代器返回的任何 JavaScript 值。done 为 true 时可省略。
+
+ +

next() 方法必须返回一个对象,该对象应当有两个属性: donevalue,如果返回了一个非对象值(比如 falseundefined),则会抛出一个 {{jsxref("TypeError")}} 异常("iterator.next() returned a non-object value")。

+
+ +
+

备注:不可能判断一个特定的对象是否实现了迭代器协议,然而,创造一个同时满足迭代器协议和可迭代协议的对象是很容易的(如下面的示例中所示)。

+ +

这样做允许一个迭代器能被各种需要可迭代对象的语法所使用。因此,很少会只实现迭代器协议,而不实现可迭代协议。

+ +
var myIterator = {
+    next: function() {
+        // ...
+    },
+    [Symbol.iterator]: function() { return this }
+}
+
+ +

使用迭代协议的例子

+ +

{{jsxref("String")}} 是一个内置的可迭代对象:

+ +
let someString = "hi";
+typeof someString[Symbol.iterator];          // "function"
+
+ +

String 的默认迭代器会依次返回该字符串的各码点(code point):

+ +
let iterator = someString[Symbol.iterator]();
+iterator + "";                               // "[object String Iterator]"
+
+iterator.next();                             // { value: "h", done: false }
+iterator.next();                             // { value: "i", done: false }
+iterator.next();                             // { value: undefined, done: true }
+ +

一些内置的语法结构——比如{{jsxref("Operators/Spread_operator", "展开语法")}}——其内部实现也使用了同样的迭代协议:

+ +
[...someString]                              // ["h", "i"]
+ +

我们可以通过提供自己的 @@iterator 方法,重新定义迭代行为:

+ +
// 必须构造 String 对象以避免字符串字面量 auto-boxing
+var someString = new String("hi");
+someString[Symbol.iterator] = function() {
+  return { // 只返回一次元素,字符串 "bye",的迭代器对象
+    next: function() {
+      if (this._first) {
+        this._first = false;
+        return { value: "bye", done: false };
+      } else {
+        return { done: true };
+      }
+    },
+    _first: true
+  };
+};
+
+ +

注意重新定义的 @@iterator 方法是如何影响内置语法结构的行为的:

+ +
[...someString];                              // ["bye"]
+someString + "";                              // "hi"
+
+ +

可迭代对象示例

+ +

内置可迭代对象

+ +

目前所有的内置可迭代对象如下:{{jsxref("String")}}、{{jsxref("Array")}}、{{jsxref("TypedArray")}}、{{jsxref("Map")}} 和 {{jsxref("Set")}},它们的原型对象都实现了 @@iterator 方法。

+ +

自定义可迭代对象

+ +

我们可以实现一个自己的可迭代对象,就像这样:

+ +
var myIterable = {};
+myIterable[Symbol.iterator] = function* () {
+    yield 1;
+    yield 2;
+    yield 3;
+};
+[...myIterable]; // [1, 2, 3]
+
+ +

接受可迭代对象的内置 API

+ +

很多 API 接受可迭代对象作为参数,例如:

+ + + +
new Map([[1, 'a'], [2, 'b'], [3, 'c']]).get(2); // "b"
+
+let myObj = {};
+
+new WeakMap([
+    [{}, 'a'],
+    [myObj, 'b'],
+    [{}, 'c']
+]).get(myObj);             // "b"
+
+new Set([1, 2, 3]).has(3); // true
+new Set('123').has('2');   // true
+
+new WeakSet(function* () {
+    yield {}
+    yield myObj
+    yield {}
+}()).has(myObj);           // true
+
+ +

另外,还有…

+ + + +

需要可迭代对象的语法

+ +

一些语句和表达式需要可迭代对象,比如 {{jsxref("Statements/for...of", "for...of")}} 循环、{{jsxref("Operators/Spread_syntax", "展开语法")}}、{{jsxref("Operators/yield*", "yield*")}},和{{jsxref("Operators/Destructuring_assignment", "解构赋值")}}。

+ +
for(let value of ["a", "b", "c"]){
+    console.log(value);
+}
+// "a"
+// "b"
+// "c"
+
+[..."abc"]; // ["a", "b", "c"]
+
+function* gen() {
+  yield* ["a", "b", "c"];
+}
+
+gen().next(); // { value: "a", done: false }
+
+[a, b, c] = new Set(["a", "b", "c"]);
+a // "a"
+
+
+ +

格式不佳的可迭代对象

+ +

如果一个可迭代对象的 @@iterator 方法不能返回迭代器对象,那么可以认为它是一个格式不佳的(Non-well-formed)可迭代对象 。

+ +

使用这样的可迭代对象很可能会导致如下的运行时(runtime)异常,或者不可预料的表现:

+ +
var nonWellFormedIterable = {}
+nonWellFormedIterable[Symbol.iterator] = () => 1
+[...nonWellFormedIterable] // TypeError: [] is not a function
+
+ +

迭代器示例

+ +

简单迭代器

+ +
function makeIterator(array) {
+    let nextIndex = 0;
+    return {
+       next: function () {
+           return nextIndex < array.length ? {
+               value: array[nextIndex++],
+               done: false
+           } : {
+               done: true
+           };
+       }
+    };
+}
+
+let it = makeIterator(['哟', '呀']);
+
+console.log(it.next().value); // '哟'
+console.log(it.next().value); // '呀'
+console.log(it.next().done);  // true
+
+ +

无穷迭代器

+ +
function idMaker() {
+    let index = 0;
+    return {
+       next: function() {
+           return {
+               value: index++,
+               done: false
+           };
+       }
+    };
+}
+
+let it = idMaker();
+
+console.log(it.next().value); // '0'
+console.log(it.next().value); // '1'
+console.log(it.next().value); // '2'
+// ...
+
+ +

使用生成器

+ +
function* makeSimpleGenerator(array) {
+    let nextIndex = 0;
+
+    while(nextIndex < array.length) {
+        yield array[nextIndex++];
+    }
+}
+
+let gen = makeSimpleGenerator(['哟', '呀']);
+
+console.log(gen.next().value); // '哟'
+console.log(gen.next().value); // '呀'
+console.log(gen.next().done);  // true
+
+
+
+function* idMaker() {
+    let index = 0;
+    while (true) {
+        yield index++;
+    }
+}
+
+let gen = idMaker();
+
+console.log(gen.next().value); // '0'
+console.log(gen.next().value); // '1'
+console.log(gen.next().value); // '2'
+// ...
+
+ +

ES2015 类 class 中的迭代器

+ +
class SimpleClass {
+  constructor(data) {
+    this.data = data
+  }
+
+  [Symbol.iterator]() {
+    // Use a new index for each iterator. This makes multiple
+    // iterations over the iterable safe for non-trivial cases,
+    // such as use of break or nested looping over the same iterable.
+    let index = 0;
+
+    return {
+      next: () => {
+        if (index < this.data.length) {
+          return {value: this.data[index++], done: false}
+        } else {
+          return {done: true}
+        }
+      }
+    }
+  }
+}
+
+const simple = new SimpleClass([1,2,3,4,5])
+
+for (const val of simple) {
+  console.log(val)   //'1' '2' '3' '4' '5'
+}
+
+ +

生成器对象到底是一个迭代器,还是一个可迭代对象?

+ +

{{jsxref("Generator", "生成器")}}对象既是迭代器,也是可迭代对象:

+ +
let aGeneratorObject = function* (){
+    yield 1;
+    yield 2;
+    yield 3;
+}();
+
+typeof aGeneratorObject.next;
+// 返回"function", 因为有一个next方法,所以这是一个迭代器
+
+typeof aGeneratorObject[Symbol.iterator];
+// 返回"function", 因为有一个@@iterator方法,所以这是一个可迭代对象
+
+aGeneratorObject[Symbol.iterator]() === aGeneratorObject;
+// 返回true, 因为@@iterator方法返回自身(即迭代器),所以这是一个格式良好的可迭代对象
+
+[...aGeneratorObject];
+// 返回[1, 2, 3]
+
+console.log(Symbol.iterator in aGeneratorObject)
+// 返回true, 因为@@iterator方法是aGeneratorObject的一个属性
+ +

规范

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-iteration', 'Iteration')}}
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/lexical_grammar/index.html b/files/zh-cn/web/javascript/reference/lexical_grammar/index.html new file mode 100644 index 0000000000..c862bf1e70 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/lexical_grammar/index.html @@ -0,0 +1,572 @@ +--- +title: 词法文法 +slug: Web/JavaScript/Reference/Lexical_grammar +tags: + - JavaScript + - Keyword + - Literal + - 关键字 + - 字面量 + - 直接量 + - 词法 + - 语法 +translation_of: Web/JavaScript/Reference/Lexical_grammar +--- +
{{JsSidebar("More")}}
+ +

这部分描述了JavaScript 的词法(lexical grammar)。ECMAScript 源码文本会被从左到右扫描,并被转换为一系列的输入元素,包括 token、控制符、行终止符、注释和空白符。ECMAScript 定义了一些关键字、字面量以及行尾分号补全的规则。

+ +

格式控制符

+ +

格式控制符用于控制对源码文本的解释,但是并不会显示出来。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
使用 Unicode 编码表示的格式控制符
代码点名称缩写说明
U+200C零宽度非结合子<ZWNJ>放置在一些经常会被当成连字的字符之间,用于将它们分别以独立形式显示(Wikipedia
U+200D零宽度结合子<ZWJ>放置在一些通常不会被标记为连字的字符之间,用于将这些字符以连字形式显示(Wikipedia
U+FEFF字节流方向标识<BOM>在脚本开头使用,除了将脚本标记为Unicode格式以外,还用来标记文本的字节流方向(Wikipedia
+ +

空白符

+ +

空白符提升了源码的可读性,并将标记 (tokens) 区分开。这些符号通常不影响源码的功能。通常可以用压缩器来移除源码中的空白,减少数据传输量。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
空白符
代码点名称缩写说明转义序列
U+0009制表符<HT>水平制表符\t
U+000B垂直制表符<VT>垂直制表符\v
U+000C分页符<FF>分页符(Wikipedia\f
U+0020空格<SP>空格
U+00A0无间断空格<NBSP>在该空格处不会换行
Others其他 Unicode 空白<USP>Wikipedia上对 Unicode 空白的介绍
+ +

行终止符

+ +

除了空白符之外,行终止符也可以提高源码的可读性。不同的是,行终止符可以影响 JavaScript 代码的执行。行终止符也会影响自动分号补全的执行。在正则表达式中,行终止符会被 \s 匹配。

+ +

在 ECMAScript 中,只有下列 Unicode 字符会被当成行终止符,其他的行终止符(比如 Next Line、NEL、U+0085 等)都会被当成空白符。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
行终止符
编码名称缩写说明转义序列
U+000A换行符<LF>在UNIX系统中起新行\n
U+000D回车符<CR>在 Commodore 和早期的 Mac 系统中起新行\r
U+2028行分隔符<LS>Wikipedia
U+2029段分隔符<PS>Wikipedia
+ +

注释

+ +

注释用来在源码中增加提示、笔记、建议、警告等信息,可以帮助阅读和理解源码。在调试时,可以用来将一段代码屏蔽掉,防止其运行。

+ +

在 JavaScript 中,有两种添加注释的方法。

+ +

第一种是单行注释(single-line comment),使用 //,会将该行中符号以后的文本都视为注释:

+ +
function comment() {
+  // 这是单行注释
+  console.log("Hello world!");
+}
+comment();
+
+ +

第二种是多行注释(multiple-line comment),使用 /* */ ,这种方式更加灵活:

+ +

比如,可以在单行内使用多行注释:

+ +
function comment() {
+  /* 单行注释 */
+  console.log("Hello world!");
+}
+comment();
+ +

也可以用来实现多行注释:

+ +
function comment() {
+  /* 多行注释,
+     直到终止符号才结束 */
+  console.log("Hello world!");
+}
+comment();
+ +

多行注释也可以用于行内注释,但这样会使代码可读性变差,所以要谨慎使用:

+ +
function comment(x) {
+  console.log("Hello " + x /* 引入x的值 */ + " !");
+}
+comment("world");
+ +

另外,块注释也可以用来屏蔽一段代码,只要将这段代码用块注释包裹起来就可以了:

+ +
function comment() {
+  /* console.log("Hello world!"); */
+}
+comment();
+ +

注释中的 console.log() 的调用始终无效。这种方式可以屏蔽任意多行的代码,也可以屏蔽一行代码的一部分。

+ +

Hashbang 注释

+ +

专门的第三个注释语法,hashbang 注释正在 ECMAScript 中标准化(参见 Hashbang 语法建议)。

+ +

Hashbang 注释的行为与单行(//)注释完全相同,但它以 #! 开头且仅在脚本或模块的绝对开头有效。还要注意,在 #! 之前不允许有任何类型的空格。注释由 #! 之后的所有字符组成直到第一行的末尾;只允许有一条这样的注释。

+ +

Hashbang 注释指定特定 JavaScript 解释器的路径要用于执行脚本。示例如下:

+ +
#!/usr/bin/env node
+
+console.log("Hello world");
+
+ +
+

注意:JavaScript 中的 hashbang 注释模仿 Unix 中的 shebangs,用于指定适当的解释器运行文件。

+
+ +
+

尽管在 hashbang 注释之前的 BOM 在浏览器中能工作,但不建议在具有 hashbang 的脚本中使用 BOM。当您尝试在 Unix/Linux 中运行脚本时,有 BOM 将不工作。因此,如果要直接从 shell 运行脚本,请使用没有 BOM 的 UTF-8。

+
+ +

您只能使用 #! 注释样式以指定 JavaScript 解释器。在所有其他情况下,只需使用 // 注释(或多行注释)。

+ +

关键字

+ +

ECMAScript 6 中的保留关键字

+ +
+ +
+ +

未来保留关键字

+ +

在 ECMAScript 规格中,这些关键字被当成关键字保留。目前它们没有特殊功能,但是在未来某个时间可能会加上。所以这些关键字不能当成标识符使用。这些关键字在严格模式和非严格模式中均不能使用。

+ + + +

以下关键字只在严格模式中被当成保留关键字:

+ +
+ +
+ + + +

以下关键字只在模块代码中被当成保留关键字:

+ + + +

之前标准中的保留关键字

+ +

这里是之前版本中的ECMAScript(1到3)中的保留关键字:

+ +
+ +
+ +

另外,直接量nulltruefalse同样不能被当成标识使用。

+ +

保留字的使用

+ +

事实上保留字是仅针对标识符(Identifier)的文法定义而言的(而不是标识符名(IdentifierName)的文法定义)。如 es5.github.com/#A.1中所描述的, 这些都是不排斥保留字的标识符名.

+ +
a.import
+a["import"]
+a = { import: "test" }.
+
+ +

另一方面,如下用法是不允许的。因为它是一个标识符,而标识符的文法定义是除保留字以外的标识符名。标识符用于函数声明式和函数表达式.

+ +
function import() {} // Illegal.
+ +

直接量

+ +

空直接量

+ +

更多信息可以参考null

+ +
null
+ +

布尔直接量

+ +

更多信息可以参考Boolean

+ +
true
+false
+ +

数值直接量

+ +

十进制

+ +
1234567890
+42
+
+// 谨慎使用 0 开头的数值:
+0888 // 转换为十进制 888
+0777 // 转换为八进制 777,十进制 511
+
+ +

请注意,十进制数值直接量可以以 0 开头,但是如果 0 以后的最高位比 8 小,数值将会被认为是八进制而不会报错。更多信息可以参考 {{bug(957513)}} 和 parseInt()

+ +

二进制

+ +

二进制表示为开头是0后接大写或小写的B(0b或者0B)。这是ECMAScript 6中的新语法,可以参考下面的浏览器兼容性表格。如果0b之后有除了0或1以外的数字,将会抛出SyntaxError:“Missing binary digits after 0b”。

+ +
var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
+var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
+var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607
+ +

八进制

+ +

八进制表示为开头是0后接大写或小写的O(0o0O)。这是ECMAScript 6中的新语法,可以参考下面的浏览器兼容性表格。如果有不在(01234567)中的数字,将会抛出SyntaxError:“Missing octal digits after 0o”。

+ +
var n = 0O755; // 493
+var m = 0o644; // 420
+
+// 用0开头也可以实现(请查看上方十进制有关部分)
+0755
+0644
+
+ +

十六进制

+ +

十六进制表示为开头是0后接大写或小写的X(0x0X)。如果有不在(0123456789ABCDEF)中的数字,将会抛出SyntaxError:“Identifier starts immediately after numeric literal”。

+ +
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
+0x123456789ABCDEF   // 81985529216486900
+0XA                 // 10
+
+ +

对象直接量

+ +

更多信息可以参考 {{jsxref("Object")}} 和对象初始化器

+ +
var o = { a: "foo", b: "bar", c: 42 };
+
+// ES6中的简略表示方法
+var a = "foo", b = "bar", c = 42;
+var o = {a, b, c};
+// 不需要这样
+var o = { a: a, b: b, c: c };
+
+ +

数组直接量

+ +

更多信息可以参考 {{jsxref("Array")}}。

+ +
[1954, 1974, 1990, 2014]
+ +

字符串直接量

+ +
'foo'
+"bar"
+ +

十六进制转义序列

+ +
'\xA9' // "©"
+
+ +

Unicode 转义序列

+ +

Unicode 转义序列要求在\u之后至少有四个字符。

+ +
'\u00A9' // "©"
+ +

Unicode 编码转义

+ +

ECMAScript 6新增特性。使用Unicode编码转义,任何字符都可以被转义为十六进制编码。最高可以用到0x10FFFF。使用单纯的Unicode转义通常需要写成分开的两半以达到相同的效果。

+ +

可以参考{{jsxref("String.fromCodePoint()")}}和{{jsxref("String.prototype.codePointAt()")}}。

+ +
'\u{2F804}'
+
+// 使用单纯 Unicode 转义
+'\uD87E\uDC04'
+ +

正则表达式直接量

+ +

更多信息可以参考 RegExp

+ +
/ab+c/g
+
+// 一个空的正则表达式直接量
+// 必须有一个空的非捕获分组
+// 以避免被当成是行注释符号
+/(?:)/
+ +

模板直接量

+ +

更多信息可以参考template strings

+ +
`string text`
+
+`string text line 1
+ string text line 2`
+
+`string text ${expression} string text`
+
+tag `string text ${expression} string text`
+ +

自动分号补全

+ +

一些 JavaScript 语句必须用分号结束,所以会被自动分号补全 (ASI)影响:

+ + + +

ECMAScript 规格提到自动分号补全的三个规则

+ +

1. 当出现一个不允许的行终止符或“}”时,会在其之前插入一个分号。

+ +
{ 1 2 } 3
+
+// 将会被 ASI 转换为
+
+{ 1 2 ;} 3;
+ +

2. 当捕获到标识符输入流的结尾,并且无法将单个输入流转换为一个完整的程序时,将在结尾插入一个分号。

+ +

在下面这段中,由于在 b++ 之间出现了一个行终止符,所以 ++ 未被当成变量 b后置运算符

+ +
a = b
+++c
+
+// 将被 ASI 转换为
+
+a = b;
+++c;
+
+ +

3. 当语句中包含语法中的限制产品后跟一个行终止符的时候,将会在结尾插入一个分号。带“这里没有行终止符”规则的语句有:

+ + + +
return
+a + b
+
+// 将被 ASI 转换为
+
+return;
+a + b;
+
+ +

规格

+ + + + + + + + + + + + + + + + + + + + + + + + +
规格状态备注
{{SpecName('ES1')}}{{Spec2("ES1")}}初始定义
{{SpecName('ES5.1', '#sec-7', 'Lexical Conventions')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-ecmascript-language-lexical-grammar', 'Lexical Grammar')}}{{Spec2('ES6')}}增加:二进制和八进制数值直接量,Unicode 编码转义直接量、模板直接量
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.grammar")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/addition_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/addition_assignment/index.html new file mode 100644 index 0000000000..9469f0f0b7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/addition_assignment/index.html @@ -0,0 +1,74 @@ +--- +title: 加法赋值 (+=) +slug: Web/JavaScript/Reference/Operators/Addition_assignment +tags: + - += +translation_of: Web/JavaScript/Reference/Operators/Addition_assignment +--- +
{{jsSidebar("Operators")}}
+ +

加法赋值操作符 (+=) 将右操作数的值添加到变量,并将结果分配给该变量。两个操作数的类型确定加法赋值运算符的行为。加法或串联是可能的。

+ +
{{EmbedInteractiveExample("pages/js/expressions-addition-assignment.html")}}
+ +
+ + + +

Syntax

+ +
Operator: x += y
+Meaning:  x  = x + y
+ +

Examples

+ +

Using addition assignment

+ +
// Assuming the following variables
+//  foo = 'foo'
+//  bar = 5
+//  baz = true
+
+// Number + Number -> addition
+bar += 2 // 7
+
+// Boolean + Number -> addition
+baz += 1 // 2
+
+// Boolean + Boolean -> addition
+baz += false // 1
+
+// Number + String -> concatenation
+bar += 'foo' // "5foo"
+
+// String + Boolean -> concatenation
+foo += false // "foofalse"
+
+// String + String -> concatenation
+foo += 'bar' // "foobar"
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.addition_assignment")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html b/files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html new file mode 100644 index 0000000000..d7fc5da786 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html @@ -0,0 +1,301 @@ +--- +title: 算术运算符 +slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators +tags: + - JavaScript + - Operator +translation_of: Web/JavaScript/Reference/Operators +--- +
{{jsSidebar("Operators")}}
+ +

算术运算符以数值(字面量或变量)作为其操作数,并返回一个单个数值。标准算术运算符是加法(+),减法(-),乘法(*)和除法(/)。

+ +
{{EmbedInteractiveExample("pages/js/expressions-arithmetic.html")}}
+ + + +

加法 (+)

+ +

加法运算符的作用是数值求和,或者字符串拼接。

+ +

语法

+ +
运算符: x + y
+
+ +

示例

+ +
// Number + Number -> 数字相加
+1 + 2 // 3
+
+// Boolean + Number -> 数字相加
+true + 1 // 2
+
+// Boolean + Boolean -> 数字相加
+false + false // 0
+
+// Number + String -> 字符串连接
+5 + "foo" // "5foo"
+
+// String + Boolean -> 字符串连接
+"foo" + false // "foofalse"
+
+// String + String -> 字符串连接
+"foo" + "bar" // "foobar"
+
+ +

减法 (-)

+ +

减法运算符使两个操作数相减,结果是它们的差值。

+ +

语法

+ +
运算符: x - y
+
+ +

示例

+ +
5 - 3 // 2
+3 - 5 // -2
+"foo" - 3 // NaN
+ +

除法 (/)

+ +

除法运算符的结果是操作数的商 ,左操作数是被除数,右操作数是除数。

+ +

语法

+ +
运算符: x / y
+
+ +

示例

+ +
1 / 2      // 在 JavaScript 中返回 0.5
+1 / 2      // 在 Java 中返回 0
+// (不需要数字是明确的浮点数)
+
+1.0 / 2.0  // 在 JavaScript 或 Java 中都返回 0.5
+
+2.0 / 0    // 在 JavaScript 中返回 Infinity
+2.0 / 0.0  // 同样返回 Infinity
+2.0 / -0.0 // 在 JavaScript 中返回 -Infinity
+ +

乘法 (*)

+ +

乘法运算符的结果是操作数的乘积。

+ +

语法

+ +
运算符: x * y
+
+ +

示例

+ +
2 * 2 // 4
+-2 * 2 // -4
+Infinity * 0 // NaN
+Infinity * Infinity // Infinity
+"foo" * 2 // NaN
+
+ +

求余 (%)

+ +

求余运算符返回第一个操作数对第二个操作数的模,即 var1 对 var2 取模,其中 var1 和 var2 是变量。取模功能就是 var1 除以 var2 的整型余数。

+ +

语法

+ +
运算符: var1 % var2
+
+ +

示例

+ +
12 % 5 // 2
+-1 % 2 // -1
+NaN % 2 // NaN
+1 % 2 // 1
+2 % 3 // 2
+-4 % 2 // -0
+5.5 % 2 // 1.5
+
+ +

幂 (**)

+ +

幂运算符返回第一个操作数做底数,第二个操作数做指数的乘方。即,var1var2,其中 var1var2 是其两个操作数。幂运算符是右结合的。a ** b ** c 等同于 a ** (b ** c)

+ +

语法

+ +
运算符: var1 ** var2
+
+ +

注解

+ +

包括 PHP 或 Python 等的大多数语言中,都包含幂运算符(一般来说符号是 ^ 或者 **)。这些语言中的幂运算符有着比其他的单目运算符(如一元 + 或一元 - )更高的优先级。但是作为例外,在 Bash 中,**  运算符被设计为比单目运算符优先级更低。在最新的 JavaScript(ES2016) 中,禁止使用带歧义的幂运算表达式。比如,底数前不能紧跟一元运算符(+/-/~/!/delete/void/typeof)。

+ +
-2 ** 2;
+// 在 Bash 中等于 4 ,而在其他语言中一般等于 -4
+// 在 JavaScript 中是错误的,因为这会有歧义
+
+-(2 ** 2);
+// -4 在 JavaScript 中能够明显体现出作者的意图
+ +

示例

+ +
2 ** 3 // 8
+3 ** 2 // 9
+3 ** 2.5 // 15.588457268119896
+10 ** -1 // 0.1
+NaN ** 2 // NaN
+
+2 ** 3 ** 2 // 512
+2 ** (3 ** 2) // 512
+(2 ** 3) ** 2 // 64
+
+ +

如果要反转求幂表达式结果的符号,你可以采用这样的方式:

+ +
-(2 ** 2) // -4
+ +

强制求幂表达式的基数为负数:

+ +
(-2) ** 2 // 4
+ +

递增 (++)

+ +

递增运算符为其操作数增加1,返回一个数值。

+ + + +

语法

+ +
运算符: x++ 或者 ++x
+
+ +

示例

+ +
// 后置
+var x = 3;
+y = x++;
+// y = 3, x = 4
+
+// 前置
+var a = 2;
+b = ++a;
+// a = 3, b = 3
+
+ +

递减 (--)

+ +

递减运算符将其操作数减去1,并返回一个数值。

+ + + +

语法

+ +
运算符: x-- or --x
+
+ +

示例

+ +
// 后置
+var x = 3;
+y = x--; // y = 3, x = 2
+
+// 前置
+var a = 2;
+b = --a; // a = 1, b = 1
+
+ +

一元负号 (-)

+ +

一元负号运算符位于操作数前面,并转换操作数的符号。

+ +

语法

+ +
运算符: -x
+
+ +

示例

+ +
var x = 3;
+y = -x; // y = -3, x = 3
+
+ +

一元正号 (+)

+ +

一元正号运算符位于其操作数前面,计算其操作数的数值,如果操作数不是一个数值,会尝试将其转换成一个数值。 尽管一元负号也能转换非数值类型,但是一元正号是转换其他对象到数值的最快方法,也是最推荐的做法,因为它不会对数值执行任何多余操作。它可以将字符串转换成整数和浮点数形式,也可以转换非字符串值 truefalse  null。小数和十六进制格式字符串也可以转换成数值。负数形式字符串也可以转换成数值(对于十六进制不适用)。如果它不能解析一个值,则计算结果为 NaN

+ +

语法

+ +
运算符: +x
+
+ +

示例

+ +
+3     // 3
++"3"   // 3
++true  // 1
++false // 0
++null  // 0
++function(val){ return val;} //NaN
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.3')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2015', '#sec-postfix-expressions')}}{{Spec2('ES2015')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2016', '#sec-postfix-expressions')}}{{Spec2('ES2016')}}Added Exponentiation operator.
{{SpecName('ES2017', '#sec-postfix-expressions')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-additive-operators')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.arithmetic")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html b/files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html new file mode 100644 index 0000000000..8bdfa28db2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html @@ -0,0 +1,157 @@ +--- +title: 数组推导式 +slug: Web/JavaScript/Reference/Operators/Array_comprehensions +tags: + - JavaScript + - Non-standard + - 参考 + - 运算符 +translation_of: Archive/Web/JavaScript/Array_comprehensions +--- +
+

非标准。不要使用!
+ 数组推导是非标准的。以后应该用 {{jsxref("Array.prototype.map")}},{{jsxref("Array.prototype.filter")}},{{jsxref("Functions/Arrow_functions", "箭头函数", "", 1)}}和{{jsxref("Operators/Spread_operator", "展开语法", "", 1)}}.。

+
+ +

{{jsSidebar("Operators")}} 

+ +

数组推导式是一种 JavaScript 表达式语法,使用它,你可以在一个原有数组的基础上快速的构造出一个新的数组。但是它已经从标准和火狐中移除。不要用它!

+ +

语法

+ +
[for (x of iterable) x]
+[for (x of iterable) if (condition) x]
+[for (x of iterable) for (y of iterable) x + y]
+
+ +

描述

+ +

在数组推导式内部,可以使用下面两种子语句:

+ + + +

每个 for-of 语句都放在与其配对的 if 语句(可以有多个,也可以完全省略)的左边,每个数组推导式中可以包含多组这样的配对,但最终选取的表达式值只能有一个,且这个值(也可以是个数组推导式,也就是说可以嵌套)只能放在推导式的最右边,紧靠着右中括号。

+ +

示例

+ +

基本的数组推导式写法

+ +
[for (i of [ 1, 2, 3 ]) i*i ];
+// [ 1, 4, 9 ]
+
+var abc = [ "A", "B", "C" ];
+[for (letters of abc) letters.toLowerCase()];
+// [ "a", "b", "c" ]
+ +

带有 if 语句的数组推导式

+ +
var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
+
+[for (year of years) if (year > 2000) year];
+// [ 2006, 2010, 2014 ]
+
+[for (year of years) if (year > 2000) if(year < 2010) year];
+// [ 2006], 和下面的写法等效:
+
+[for (year of years) if (year > 2000 && year < 2010) year];
+// [ 2006]
+
+ +

用数组推导式比用数组的 mapfilter 方法更简洁

+ +

对比数组的 {{jsxref("Array.map", "map")}} 和 {{jsxref("Array.filter", "filter")}} 方法:

+ +
var numbers = [ 1, 2, 3 ];
+
+numbers.map(function (i) { return i * i });
+[for (i of numbers) i*i ];
+// 返回值都是 [ 1, 4, 9 ]
+
+numbers.filter(function (i) { return i < 3 });
+[for (i of numbers) if (i < 3) i];
+// 返回值都是 [ 1, 2 ]
+
+ +

带有两个数组的数组推导式

+ +

用两个 for-of 语句迭代两个不同的数组:

+ +
var numbers = [ 1, 2, 3 ];
+var letters = [ "a", "b", "c" ];
+
+var cross = [for (i of numbers) for (j of letters) i+j];
+// [ "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c" ]
+
+var grid = [for (i of numbers) [for (j of letters) i+j]];
+// [
+//  ["1a", "1b", "1c"],
+//  ["2a", "2b", "2c"],
+//  ["3a", "3b", "3c"]
+// ]
+
+[for (i of numbers) if (i > 1) for (j of letters) if(j > "a") i+j]
+// ["2b", "2c", "3b", "3c"],和下面的写法等效:
+
+[for (i of numbers) for (j of letters) if (i > 1) if(j > "a") i+j]
+// ["2b", "2c", "3b", "3c"]
+
+[for (i of numbers) if (i > 1) [for (j of letters) if(j > "a") i+j]]
+// [["2b", "2c"], ["3b", "3c"]],和下面的写法不等效:
+
+[for (i of numbers) [for (j of letters) if (i > 1) if(j > "a") i+j]]
+// [[], ["2b", "2c"], ["3b", "3c"]]
+
+ +

规范

+ +

最初起草在ECMAScript 6草案中,但在第27版(2014年8月)中被移除。 请参阅ES 6的旧修订版的规范语义。

+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.array_comprehensions")}}

+ +

同旧版的JS1.7/JS1.8数组推导的不同之处

+ +

 

+ +
JS1.7/JS1.8数组推导 在Gecko的46版本中已经被移除了 ({{bug(1220564)}}).
+ +

旧版数组推导语法 (请不要再使用了!):

+ +
[X for (Y in Z)]
+[X for each (Y in Z)]
+[X for (Y of Z)]
+
+ +

不同点:

+ + + +

点击查看 Bug 1220564, comment 42 并提出建设性建议.

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/assignment/index.html b/files/zh-cn/web/javascript/reference/operators/assignment/index.html new file mode 100644 index 0000000000..eba07d8890 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/assignment/index.html @@ -0,0 +1,62 @@ +--- +title: 赋值运算符(=) +slug: Web/JavaScript/Reference/Operators/Assignment +tags: + - JavaScript + - 参考 + - 操作者 + - 语言特性 + - 赋值运算符 +translation_of: Web/JavaScript/Reference/Operators/Assignment +--- +
{{jsSidebar("Operators")}}
+ +

简单赋值操作符(=)用于为变量赋值。赋值表达式本身的值为其完成后被赋值的变量的值。为了给多个变量赋一个值,可以链式使用赋值操作符。

+ +
{{EmbedInteractiveExample("pages/js/expressions-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x = y
+
+ +

示例

+ +

简单赋值和链式赋值

+ +
// 假设已经存在以下变量
+//  x = 5
+//  y = 10
+//  z = 25
+
+x = y     // x 为 10
+x = y = z // x, y 都为 25
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.operators.assignment")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html b/files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html new file mode 100644 index 0000000000..5d500538b4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html @@ -0,0 +1,412 @@ +--- +title: 赋值运算符 +slug: Web/JavaScript/Reference/Operators/Assignment_Operators +tags: + - JavaScript + - 运算符 +translation_of: Web/JavaScript/Reference/Operators#Assignment_operators +--- +
{{jsSidebar("Operators")}}
+ +

赋值运算符(assignment operator)基于右值(right operand)的值,给左值(left operand)赋值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-assignment.html")}}
+ + + +

概述

+ +

基本的赋值运算符是等号(=),该运算符把它右边的运算值赋给左边。即,x = y 把 y 的值赋给 x。 其他的赋值运算符通常是标准运算符的简写形式,如下面的定义与示例。 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称简写形式含义
赋值(Assignment)x = yx = y
加赋值(Addition assignment)x += yx = x + y
减赋值(Subtraction assignment)x -= yx = x - y
乘赋值(Multiplication assigment)x *= yx = x * y
除赋值(Division assignment)x /= yx = x / y
模赋值(Remainder assignment)x %= yx = x % y
指数赋值(Exponentiation assignment)x **= yx = x ** y
左移赋值(Left shift assignment)x <<= yx = x << y
右移赋值(Right shift assignment)x >>= yx = x >> y
无符号右移赋值(Unsigned right shift assignment)x >>>= yx = x >>> y
按位与赋值(Bitwise AND assignment)x &= yx = x & y
按位异或赋值(Bitwise XOR assignment)x ^= yx = x ^ y
按位或赋值(Bitwise OR assignment)x |= yx = x | y
+ +

赋值

+ +

简单的赋值运算符,把一个值赋给一个变量。为了把一个值赋给多个变量,可以以链式使用赋值运算符。参考下例:

+ +

语法

+ +
Operator: x = y
+
+ +

示例

+ +
// Assuming the following variables
+//  x = 5
+//  y = 10
+//  z = 25
+
+x = y     // x is 10
+x = y = z // x, y and z are all 25
+
+ +

加赋值(Addition assignment)

+ +

加赋值运算符把一个右值与一个变量相加,然后把相加的结果赋给该变量。两个操作数的类型决定了加赋值运算符的行为。算术相加或字符串连接都有可能。更多细节参考 {{jsxref("Operators/Arithmetic_Operators", "addition operator", "#Addition", 1)}}。

+ +

语法

+ +
Operator: x += y
+Meaning:  x  = x + y
+
+ +

示例

+ +
// 定义下列变量
+//  foo = 'foo'
+//  bar = 5
+//  baz = true
+
+
+// Number + Number -> addition
+bar += 2 // 7
+
+// Boolean + Number -> addition
+baz += 1 // 2
+
+// Boolean + Boolean -> addition
+baz += false // 1
+
+// Number + String -> concatenation
+bar += 'foo' // "5foo"
+
+// String + Boolean -> concatenation
+foo += false // "foofalse"
+
+// String + String -> concatenation
+foo += 'bar' // "foobar"
+
+ +

减赋值(Subtraction assignment)

+ +

减赋值运算符使一个变量减去右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "subtraction operator", "#Subtraction", 1)}} 。

+ +

语法

+ +
Operator: x -= y
+Meaning:  x  = x - y
+
+ +

示例

+ +
// 假定已定义了下面的变量
+//  bar = 5
+
+bar -= 2     // 3
+bar -= "foo" // NaN
+
+ +

乘赋值(Multiplication assignment)

+ +

乘赋值运算符使一个变量乘以右值,然后把相成的结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "multiplication operator", "#Multiplication", 1)}}。

+ +

语法

+ +
Operator: x *= y
+Meaning:  x  = x * y
+
+ +

示例

+ +
// 假定已定义了下面的变量
+//  bar = 5
+
+bar *= 2     // 10
+bar *= 'foo' // NaN
+
+ +

除赋值(Division assignment)

+ +

除赋值运算符使一个变量除以右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "division operator", "#Division", 1)}}。

+ +

语法

+ +
Operator: x /= y
+Meaning:  x  = x / y
+
+ +

示例

+ +
// 假定已定义了下面的变量
+//  bar = 5
+
+bar /= 2     // 2.5
+bar /= "foo" // NaN
+bar /= 0     // Infinity
+
+ +

模赋值(Remainder assignment)

+ +

模赋值运算符使一个变量除以右值,然后把余数赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "remainder operator", "#Remainder", 1)}}。

+ +

语法

+ +
Operator: x %= y
+Meaning:  x  = x % y
+
+ +

示例

+ +
// Assuming the following variable
+//  bar = 5
+
+bar %= 2     // 1
+bar %= 'foo' // NaN
+bar %= 0     // NaN
+
+ +

指数赋值(Exponentiation assignment)

+ +

指数赋值运算符使一个变量为底数、以右值为指数的指数运算(乘方)结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "算术运算符", "#Exponentiation", 1)}}。

+ +

语法

+ +
语法: x **= y
+含义:  x  = x ** y
+
+ +

示例

+ +
// Assuming the following variable
+//  bar = 5
+
+bar **= 2     // 25
+bar **= 'foo' // NaN
+ +

左移赋值(Left shift assignment)

+ +

左移赋值运算符使变量向左移动指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "left shift operator", "#Left_shift", 1)}}。

+ +

语法

+ +
Operator: x <<= y
+Meaning:  x   = x << y
+
+ +

示例

+ +
var bar = 5; //  (00000000000000000000000000000101)
+bar <<= 2; // 20 (00000000000000000000000000010100)
+
+ +

右移赋值(Right shift assignment)

+ +

右移赋值运算符使变量向右移指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "right shift operator", "#Right_shift", 1)}}。

+ +

语法

+ +
Operator: x >>= y
+Meaning:  x   = x >> y
+
+ +

示例

+ +
var bar = 5; //   (00000000000000000000000000000101)
+bar >>= 2;   // 1 (00000000000000000000000000000001)
+
+var bar = -5; //    (-00000000000000000000000000000101)
+bar >>= 2;  // -2 (-00000000000000000000000000000010)
+
+ +

无符号右移赋值(Unsigned right shift assignment)

+ +

无符号右移赋值运算符向右移动指定数量的比特位,然后把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", " unsigned right shift operator", "#Unsigned_right_shift", 1)}}。

+ +

语法

+ +
Operator: x >>>= y
+Meaning:  x    = x >>> y
+
+ +

示例

+ +
var bar = 5; //   (00000000000000000000000000000101)
+bar >>>= 2;  // 1 (00000000000000000000000000000001)
+
+var bar = -5; // (-00000000000000000000000000000101)
+bar >>>= 2; // 1073741822 (00111111111111111111111111111110)
+ +

按位与赋值(Bitwise AND assignment)

+ +

按位与赋值运算符使用两个操作值的二进制表示,执行按位与运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise AND operator", "#Bitwise_AND", 1)}}。

+ +

语法

+ +
Operator: x &= y
+Meaning:  x  = x & y
+
+ +

示例

+ +
var bar = 5;
+// 5:     00000000000000000000000000000101
+// 2:     00000000000000000000000000000010
+bar &= 2; // 0
+
+ +

按位异或赋值(Bitwise XOR assignment)

+ +

按位异或赋值运算符使用两个操作值的二进制表示,执行二进制异或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise XOR operator", "#Bitwise_XOR", 1)}}。

+ +

语法

+ +
Operator: x ^= y
+Meaning:  x  = x ^ y
+
+ +

示例

+ +
var bar = 5;
+bar ^= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+
+ +

按位或赋值(Bitwise OR assignment)

+ +

按位或赋值运算符使用两个操作值的二进制表示,执行按位或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise OR operator", "#Bitwise_OR", 1)}}。

+ +

语法

+ +
Operator: x |= y
+Meaning:  x  = x | y
+
+ +

示例

+ +
var bar = 5;
+bar |= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+
+ +

示例

+ +

带有赋值运算符的左值(Left operand)

+ +

在某些不常见的情况下,赋值运算符(如 x += y)并不等同于表达式( x = x + y)。当一个赋值运算符的左值包含有一个赋值运算符时,左值只会被求值一次。例如:

+ +
a[i++] += 5         // i 执行一次求值
+a[i++] = a[i++] + 5 // i 执行两次求值
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-assignment-operators', 'Assignment operators')}}{{Spec2('ES2015')}}
{{SpecName('ES5.1', '#sec-11.13', 'Assignment operators')}}{{Spec2('ES5.1')}}
{{SpecName('ES1', '#sec-11.13', 'Assignment operators')}}{{Spec2('ES1')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.assignment")}}

+ +

相关链接

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" "b/files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" new file mode 100644 index 0000000000..eebfd13ca2 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" @@ -0,0 +1,98 @@ +--- +title: async function expression +slug: Web/JavaScript/Reference/Operators/async允许声明一个函数为一个包含异步操作的函数 +tags: + - JavaScript + - 函数 + - 基本表达式 + - 实验性内容 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/async_function +--- +
{{jsSidebar("Operators")}}
+ +
 
+ +

async function 关键字用来在表达式中定义异步函数。当然,你也可以用 {{jsxref('Statements/async_function', '异步函数语句')}} 来定义。

+ +

语法

+ +
async function [name]([param1[, param2[, ..., paramN]]]) { statements }
+ +

参数

+ +
+
name
+
此异步函数的名称,可省略。如果省略则这个函数将成为匿名函数。该名称仅可在本函数中使用。
+
paramN
+
传入函数的形参名称。
+
statements
+
组成函数体的语句。
+
+ +

描述

+ +

异步函数表达式与 {{jsxref('Statements/async_function', '异步函数语句')}} 非常相似,语法也基本相同。它们之间的主要区别在于异步函数表达式可以省略函数名称来创建一个匿名函数。另外,异步函数表达式还可以用在 {{Glossary("IIFE")}} (立即执行函数表达式,Immediately Invoked Function Expression) 中,更多信息见 {{jsxref('Reference/Functions', '函数')}}。

+ +

示例

+ +

一个简单例子

+ +
function resolveAfter2Seconds(x) {
+  return new Promise(resolve => {
+    setTimeout(() => {
+      resolve(x);
+    }, 2000);
+  });
+};
+
+// async function expression assigned to a variable
+var add1 = async function(x) {
+  var a = await resolveAfter2Seconds(20);
+  var b = await resolveAfter2Seconds(30);
+  return x + a + b;
+}
+
+add1(10).then(v => {
+  console.log(v);  // 4 秒后打印 60
+});
+
+(async function(x) { // async function expression used as an IIFE
+  var p_a = resolveAfter2Seconds(20);
+  var p_b = resolveAfter2Seconds(30);
+  return x + await p_a + await p_b;
+})(10).then(v => {
+  console.log(v);  // 2 秒后打印 60
+});
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}{{Spec2('ESDraft')}}ES2017 中的初始定义
+ +

浏览器兼容性

+ +
{{Compat("javascript.operators.async_function_expression")}}
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/await/index.html b/files/zh-cn/web/javascript/reference/operators/await/index.html new file mode 100644 index 0000000000..fe95e7ddf2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/await/index.html @@ -0,0 +1,158 @@ +--- +title: await +slug: Web/JavaScript/Reference/Operators/await +tags: + - JavaScript + - Promise + - await + - 实验性 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/await +--- +
{{jsSidebar("Operators")}}
+ +

await  操作符用于等待一个{{jsxref("Promise")}} 对象。它只能在异步函数 {{jsxref("Statements/async_function", "async function")}} 中使用。

+ +

语法

+ +
[返回值] = await 表达式;
+ +
+
表达式
+
一个 {{jsxref("Promise")}} 对象或者任何要等待的值。
+
返回值
+
+

返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。

+
+
+ +

描述

+ +

await 表达式会暂停当前 {{jsxref("Statements/async_function", "async function")}} 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 {{jsxref("Statements/async_function", "async function")}}。

+ +

若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。

+ +

另外,如果 await 操作符后的表达式的值不是一个 Promise,则返回该值本身。

+ +

例子

+ +

如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。

+ +
function resolveAfter2Seconds(x) {
+  return new Promise(resolve => {
+    setTimeout(() => {
+      resolve(x);
+    }, 2000);
+  });
+}
+
+async function f1() {
+  var x = await resolveAfter2Seconds(10);
+  console.log(x); // 10
+}
+f1();
+
+
+ +

如果该值不是一个 Promise,await 会把该值转换为已正常处理的Promise,然后等待其处理结果。

+ +
async function f2() {
+  var y = await 20;
+  console.log(y); // 20
+}
+f2();
+
+ +

如果 Promise 处理异常,则异常值被抛出。

+ +
async function f3() {
+  try {
+    var z = await Promise.reject(30);
+  } catch (e) {
+    console.log(e); // 30
+  }
+}
+f3();
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Async Function', '#async-function-definitions', 'async function')}}{{Spec2('Async Function')}}提案
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerEdgeOperaSafari (WebKit)
基本支持{{CompatChrome(55)}}{{CompatGeckoDesktop("52.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatOpera(42)}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
 基本支持{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("52.0")}}{{CompatUnknown}}{{CompatOpera(42)}}{{CompatUnknown}}{{CompatChrome(55)}}
+
+ +

查看更多

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_and_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_and_assignment/index.html new file mode 100644 index 0000000000..5c92f0196c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_and_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: 按位与赋值(&=) +slug: Web/JavaScript/Reference/Operators/Bitwise_AND_assignment +tags: + - JavaScript + - 按位与赋值运算 + - 操作符运算 +translation_of: Web/JavaScript/Reference/Operators/Bitwise_AND_assignment +--- +
{{jsSidebar("Operators")}}
+ +
按位与赋值运算符(&=)表示两个操作数的二进制,对它们进行按位AND运算并将结果分配给变量。
+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-and-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x &= y
+Meaning:  x  = x & y
+
+ +

例子

+ +

按位与赋值运算

+ +
let a = 5;
+// 5:     00000000000000000000000000000101
+// 2:     00000000000000000000000000000010
+a &= 2; // 0
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_and_assignment")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_not/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_not/index.html new file mode 100644 index 0000000000..d0dfd8ca78 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_not/index.html @@ -0,0 +1,100 @@ +--- +title: 按位非 (~) +slug: Web/JavaScript/Reference/Operators/Bitwise_NOT +tags: + - JavaScript + - 位操作符 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/Bitwise_NOT +--- +
{{jsSidebar("Operators")}}
+ +

按位非运算符(~),反转操作数的位。

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-not.html")}}
+ +
+ + + +

语法

+ +
~a
+
+ +

描述

+ +

操作数被转换为32位二进制表示(0和1)。超过32位的数字将丢弃其最高有效位。如下例子中,超过32位的整数转换为32位整数:

+ +
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+ +

第一个操作数中的每个位都与第二个操作数中的相应位配对:第一位到第一位,第二位到第二位,依此类推。

+ +

将运算符应用于每对位,然后按位构造结果。

+ +

非运算的真值表:

+ + + + + + + + + + + + + + + + + + +
aNOT a
01
10
+ +
 9 (base 10) = 00000000000000000000000000001001 (base 2)
+               --------------------------------
+~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
+
+ +

按位非运算时,任何数字x的运算结果都是-(x + 1)。例如,〜-5运算结果为4

+ +

Note that due to using 32-bit representation for numbers both ~-1 and ~4294967295 (232-1) results in 0.

+ +

请注意,由于对数字~-1~4294967295 (232-1) 使用32位表示形式,结果均为0。

+ +

例子

+ +

使用按位取反

+ +
~0;  // -1
+~-1; // 0
+~1;  // -2
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-unary-operators', 'Unary NOT expression')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_not")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html new file mode 100644 index 0000000000..48ca962238 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html @@ -0,0 +1,755 @@ +--- +title: 按位操作符 +slug: Web/JavaScript/Reference/Operators/Bitwise_Operators +tags: + - js ^ & Bitwise Operators +translation_of: Web/JavaScript/Reference/Operators +--- +
{{jsSidebar("Operators")}}
+ +

概述

+ +

按位操作符(Bitwise operators) 将其操作数(operands)当作32位的比特序列(由0和1组成),而不是十进制、十六进制或八进制数值。例如,十进制数9,用二进制表示则为1001。按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。

+ +

下面的表格总结了JavaScript中的按位操作符:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符用法描述
按位与( AND)a & b对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。
按位或(OR)a | b对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。
按位异或(XOR)a ^ b对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。
按位非(NOT)~ a反转操作数的比特位,即0变成1,1变成0。
左移(Left shift)a << b将 a 的二进制形式向左移 b (< 32) 比特位,右边用0填充。
有符号右移a >> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位。
无符号右移a >>> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。
+ +

有符号32位整数

+ +

所有的按位操作符的操作数都会被转成补码(two's complement)形式的有符号32位整数。补码形式是指一个数的负对应值(negative counterpart)(如 5和-5)为数值的所有比特位反转后,再加1。反转比特位即该数值进行’非‘位运算,也即该数值的反码。例如下面为整数314的二进制编码:

+ +
00000000000000000000000100111010
+
+ +

下面编码 ~314,即 314 的反码:

+ +
11111111111111111111111011000101
+
+ +

最后,下面编码 -314,即 314 的反码再加1:

+ +
11111111111111111111111011000110
+
+ +

补码保证了当一个数是正数时,其最左的比特位是0,当一个数是负数时,其最左的比特位是1。因此,最左边的比特位被称为符号位(sign bit)。

+ +

0 是所有比特数字0组成的整数。

+ +
0 (base 10) = 00000000000000000000000000000000 (base 2)
+
+ +

-1 是所有比特数字1组成的整数。

+ +
-1 (base 10) = 11111111111111111111111111111111 (base 2)
+
+ +

-2147483648(十六进制形式:-0x80000000)是除了最左边为1外,其他比特位都为0的整数。

+ +
-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
+
+ +

2147483647(十六进制形式:0x7fffffff)是除了最左边为0外,其他比特位都为1的整数。

+ +
2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
+
+ +

数字-21474836482147483647 是32位有符号数字所能表示的最小和最大整数。

+ +

按位逻辑操作符

+ +

从概念上讲,按位逻辑操作符按遵守下面规则:

+ + + +

& (按位与)

+ +

对每对比特位执行与(AND)操作。只有 a 和 b 都是 1 时,a AND b 才是 1。与操作的真值表如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba AND b
000
010
100
111
+ +
     9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
+
+ +

将任一数值 x 与 0 执行按位与操作,其结果都为 0。将任一数值 x 与 -1 执行按位与操作,其结果都为 x。

+ +

| (按位或)

+ +

对每一对比特位执行或(OR)操作。如果 a 或 b 为 1,则 a OR b 结果为 1。或操作的真值表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba OR b
000
011
101
111
+ +
     9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
+
+ +

将任一数值 x 与 0 进行按位或操作,其结果都是 x。将任一数值 x 与 -1 进行按位或操作,其结果都为 -1。

+ +

补充一些例子:

+ +
1 | 0 ;                       // 1
+
+1.1 | 0 ;                     // 1
+
+'asfdasfda' | 0 ;             // 0
+
+0 | 0 ;                       // 0
+
+(-1) | 0 ;                    // -1
+
+(-1.5646) | 0 ;               // -1
+
+[] | 0 ;                      // 0
+
+({}) | 0 ;                    // 0
+
+"123456" | 0 ;            // 123456
+
+1.23E2 | 0;               // 123
+
+1.23E12 | 0;              // 1639353344
+
+-1.23E2 | 0;              // -123
+
+-1.23E12 | 0;             // -1639353344
+ +

^ (按位异或)

+ +

对每一对比特位执行异或(XOR)操作。当 a 和 b 不相同时,a XOR b 的结果为 1。异或操作真值表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba XOR b
000
011
101
110
+ +
     9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
+
+ +

将任一数值 x 与 0 进行异或操作,其结果为 x。将任一数值 x 与 -1 进行异或操作,其结果为 ~x。

+ +

~ (按位非)

+ +

对每一个比特位执行非(NOT)操作。NOT a 结果为 a 的反转(即反码)。非操作的真值表:

+ + + + + + + + + + + + + + + + +
aNOT a
01
10
+ +
 9 (base 10) = 00000000000000000000000000001001 (base 2)
+               --------------------------------
+~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
+
+ +

对任一数值 x 进行按位非操作的结果为 -(x + 1)。例如,~5 结果为 -6。

+ +

与 indexOf 一起使用示例:

+ +
var str = 'rawr';
+var searchFor = 'a';
+
+// 这是 if (-1*str.indexOf('a') <= 0) 条件判断的另一种方法
+if (~str.indexOf(searchFor)) {
+  // searchFor 包含在字符串中
+} else {
+  // searchFor 不包含在字符串中
+}
+
+// (~str.indexOf(searchFor))的返回值
+// r == -1
+// a == -2
+// w == -3
+
+ +

按位移动操作符

+ +

按位移动操作符有两个操作数:第一个是要被移动的数字,而第二个是要移动的长度。移动的方向根据操作符的不同而不同。

+ +

按位移动会先将操作数转换为大端字节序顺序(big-endian order)的32位整数,并返回与左操作数相同类型的结果。右操作数应小于 32位,否则只有最低 5 个字节会被使用。

+ +
注:Big-Endian:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端,
+又称为"高位编址"。
+Big-Endian是最直观的字节序:
+①把内存地址从左到右按照由低到高的顺序写出;
+②把值按照通常的高位到低位的顺序写出;
+③两者对照,一个字节一个字节的填充进去。
+ +

<< (左移)

+ +

该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充。

+ +

For example, 9 << 2 yields 36:

+ +
     9 (base 10): 00000000000000000000000000001001 (base 2)
+                  --------------------------------
+9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
+
+ +

在数字 x 上左移 y 比特得到 x * 2y.

+ +

>> (有符号右移)

+ +

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。

+ +

例如, 9 >> 2 得到 2:

+ +
     9 (base 10): 00000000000000000000000000001001 (base 2)
+                  --------------------------------
+9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

相比之下, -9 >> 2 得到 -3,因为符号被保留了。

+ +
     -9 (base 10): 11111111111111111111111111110111 (base 2)
+                   --------------------------------
+-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
+
+ +

>>> (无符号右移)

+ +

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)

+ +

对于非负数,有符号右移和无符号右移总是返回相同的结果。例如 9 >>> 29 >> 2 一样返回 2:

+ +
      9 (base 10): 00000000000000000000000000001001 (base 2)
+                   --------------------------------
+9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

但是对于负数却不尽相同。 -9 >>> 2 产生 1073741821 这和 -9 >> 2 不同:

+ +
      -9 (base 10): 11111111111111111111111111110111 (base 2)
+                    --------------------------------
+-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
+
+ +

示例

+ +

例子:标志位与掩码

+ +

位运算经常被用来创建、处理以及读取标志位序列——一种类似二进制的变量。虽然可以使用变量代替标志位序列,但是这样可以节省内存(1/32)。

+ +

例如,有 4 个标志位:

+ + + +

标志位通过位序列 DCBA 来表示。当一个位被置位 (set) 时,它的值为 1 。当被清除 (clear) 时,它的值为 0 。例如一个变量 flags 的二进制值为 0101:

+ +
var flags = 5;   // 二进制 0101
+
+ +

这个值表示:

+ + + +

因为位运算是 32 位的, 0101 实际上是 00000000000000000000000000000101。因为前面多余的 0 没有任何意义,所以他们可以被忽略。

+ +

掩码 (bitmask) 是一个通过与/或来读取标志位的位序列。典型的定义每个标志位的原语掩码如下:

+ +
var FLAG_A = 1; // 0001
+var FLAG_B = 2; // 0010
+var FLAG_C = 4; // 0100
+var FLAG_D = 8; // 1000
+
+ +

新的掩码可以在以上掩码上使用逻辑运算创建。例如,掩码 1011 可以通过 FLAG_A、FLAG_B 和 FLAG_D 逻辑或得到:

+ +
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
+
+ +

某个特定的位可以通过与掩码做逻辑与运算得到,通过与掩码的与运算可以去掉无关的位,得到特定的位。例如,掩码 0100 可以用来检查标志位 C 是否被置位:

+ +
// 如果我们有 cat
+if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
+   // do stuff
+}
+
+ +

一个有多个位被置位的掩码表达任一/或者的含义。例如,以下两个表达是等价的:

+ +
// 如果我们有 bat 或者 cat 至少一个
+// (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
+if ((flags & FLAG_B) || (flags & FLAG_C)) {
+   // do stuff
+}
+
+ +
// 如果我们有 bat 或者 cat 至少一个
+var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
+if (flags & mask) { // 0101 & 0110 => 0100 => true
+   // do stuff
+}
+
+ +

可以通过与掩码做或运算设置标志位,掩码中为 1 的位可以设置对应的位。例如掩码 1100 可用来设置位 C 和 D:

+ +
// 我们有 cat 和 duck
+var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
+flags |= mask;   // 0101 | 1100 => 1101
+
+ +

可以通过与掩码做与运算清除标志位,掩码中为 0 的位可以设置对应的位。掩码可以通过对原语掩码做非运算得到。例如,掩码 1010 可以用来清除标志位 A 和 C :

+ +
// 我们没有 ant 也没有 cat
+var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
+flags &= mask;   // 1101 & 1010 => 1000
+
+ +

如上的掩码同样可以通过 ~FLAG_A & ~FLAG_C 得到(德摩根定律):

+ +
// 我们没有 ant 也没有 cat
+var mask = ~FLAG_A & ~FLAG_C;
+flags &= mask;   // 1101 & 1010 => 1000
+
+ +

标志位可以使用异或运算切换。所有值为 1 的位可以切换对应的位。例如,掩码 0110 可以用来切换标志位 B 和 C:

+ +
// 如果我们以前没有 bat ,那么我们现在有 bat
+// 但是如果我们已经有了一个,那么现在没有了
+// 对 cat 也是相同的情况
+var mask = FLAG_B | FLAG_C;
+flags = flags ^ mask;   // 1100 ^ 0110 => 1010
+
+ +

最后,所有标志位可以通过非运算翻转:

+ +
// entering parallel universe...
+flags = ~flags;    // ~1010 => 0101
+
+ +

转换片段

+ +

将一个二进制数的 String 转换为十进制的 Number:

+ +
var sBinString = "1011";
+var nMyNumber = parseInt(sBinString, 2);
+alert(nMyNumber); // 打印 11
+
+ +

将一个十进制的 Number 转换为二进制数的 String:

+ +
var nMyNumber = 11;
+var sBinString = nMyNumber.toString(2);
+alert(sBinString); // 打印 1011
+
+ +

自动化掩码创建

+ +

如果你需要从一系列的 Boolean 值创建一个掩码,你可以:

+ +
function createMask () {
+  var nMask = 0, nFlag = 0, nLen = arguments.length > 32 ? 32 : arguments.length;
+  for (nFlag; nFlag < nLen; nMask |= arguments[nFlag] << nFlag++);
+  return nMask;
+}
+var mask1 = createMask(true, true, false, true); // 11, i.e.: 1011
+var mask2 = createMask(false, false, true); // 4, i.e.: 0100
+var mask3 = createMask(true); // 1, i.e.: 0001
+// etc.
+
+alert(mask1); // 打印 11
+
+ +

逆算法:从掩码得到布尔数组

+ +

如果你希望从掩码得到得到 Boolean Array

+ +
function arrayFromMask (nMask) {
+  // nMask 必须介于 -2147483648 和 2147483647 之间
+  if (nMask > 0x7fffffff || nMask < -0x80000000) {
+    throw new TypeError("arrayFromMask - out of range");
+  }
+  for (var nShifted = nMask, aFromMask = []; nShifted;
+       aFromMask.push(Boolean(nShifted & 1)), nShifted >>>= 1);
+  return aFromMask;
+}
+
+var array1 = arrayFromMask(11);
+var array2 = arrayFromMask(4);
+var array3 = arrayFromMask(1);
+
+alert("[" + array1.join(", ") + "]");
+// 打印 "[true, true, false, true]", i.e.: 11, i.e.: 1011
+
+ +

你可以同时测试以上两个算法……

+ +
var nTest = 19; // our custom mask
+var nResult = createMask.apply(this, arrayFromMask(nTest));
+
+alert(nResult); // 19
+
+ +

仅仅由于教学目的 (因为有 Number.toString(2) 方法),我们展示如何修改 arrayFromMask 算法通过 Number 返回二进制的 String,而非 Boolean Array:

+ +
function createBinaryString (nMask) {
+  // nMask must be between -2147483648 and 2147483647
+  for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32;
+       nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
+  return sMask;
+}
+
+var string1 = createBinaryString(11);
+var string2 = createBinaryString(4);
+var string3 = createBinaryString(1);
+
+alert(string1);
+// 打印 00000000000000000000000000001011, i.e. 11
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-11.4.8', 'Bitwise NOT operator')}}
+ {{SpecName('ES5.1', '#sec-11.7', 'Bitwise shift operators')}}
+ {{SpecName('ES5.1', '#sec-11.10', 'Binary bitwise operators')}}
{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-bitwise-not-operator', 'Bitwise NOT operator')}}
+ {{SpecName('ES6', '#sec-bitwise-shift-operators', 'Bitwise shift operators')}}
+ {{SpecName('ES6', '#sec-binary-bitwise-operators', 'Binary bitwise operators')}}
{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Bitwise NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Left shift (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Right shift (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Unsigned right shift (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Bitwise NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Left shift (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Right shift (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Unsigned right shift (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_or/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_or/index.html new file mode 100644 index 0000000000..dcd9c54de0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_or/index.html @@ -0,0 +1,108 @@ +--- +title: Bitwise OR (|) +slug: Web/JavaScript/Reference/Operators/Bitwise_OR +translation_of: Web/JavaScript/Reference/Operators/Bitwise_OR +--- +
{{jsSidebar("Operators")}}
+ +

The bitwise OR operator (|) returns a 1 in each bit position for which the corresponding bits of either or both operands are 1s.

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-or.html")}}
+ + + +

语法

+ +
a | b
+
+ +

描述

+ +

The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32 bit integer:

+ +
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+ +

Each bit in the first operand is paired with the corresponding bit in the second operand: first bit to first bit, second bit to second bit, and so on.

+ +

The operator is applied to each pair of bits, and the result is constructed bitwise.

+ +

The truth table for the OR operation is:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba OR b
000
011
101
111
+ +
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
+
+ +

Bitwise ORing any number x with 0 yields x.

+ +

例子

+ +

Using bitwise OR

+ +
// 9  (00000000000000000000000000001001)
+// 14 (00000000000000000000000000001110)
+
+14 | 9;
+// 15 (00000000000000000000000000001111)
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-BitwiseORExpression', 'Bitwise OR expression')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_or")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_or_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_or_assignment/index.html new file mode 100644 index 0000000000..752a80154a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_or_assignment/index.html @@ -0,0 +1,57 @@ +--- +title: Bitwise OR assignment (|=) +slug: Web/JavaScript/Reference/Operators/Bitwise_OR_assignment +translation_of: Web/JavaScript/Reference/Operators/Bitwise_OR_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The bitwise OR assignment operator (|=) uses the binary representation of both operands, does a bitwise OR operation on them and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-or-assignment.html")}}
+ + + +

语法

+ +
Operator: x |= y
+Meaning:  x  = x | y
+ +

Examples

+ +

Using bitwise OR assignment

+ +
let a = 5;
+a |= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.bitwise_or_assignment")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_xor/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_xor/index.html new file mode 100644 index 0000000000..4bb149667d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_xor/index.html @@ -0,0 +1,108 @@ +--- +title: Bitwise XOR (^) +slug: Web/JavaScript/Reference/Operators/Bitwise_XOR +translation_of: Web/JavaScript/Reference/Operators/Bitwise_XOR +--- +
{{jsSidebar("Operators")}}
+ +

The bitwise XOR operator (^) returns a 1 in each bit position for which the corresponding bits of either but not both operands are 1s.

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-xor.html")}}
+ + + +

语法

+ +
a ^ b
+
+ +

描述

+ +

The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32 bit integer:

+ +
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+ +

Each bit in the first operand is paired with the corresponding bit in the second operand: first bit to first bit, second bit to second bit, and so on.

+ +

The operator is applied to each pair of bits, and the result is constructed bitwise.

+ +

The truth table for the XOR operation is:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba XOR b
000
011
101
110
+ +
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
+
+ +

Bitwise XORing any number x with 0 yields x.

+ +

Examples

+ +

Using bitwise XOR

+ +
// 9  (00000000000000000000000000001001)
+// 14 (00000000000000000000000000001110)
+
+14 ^ 9;
+// 7  (00000000000000000000000000000111)
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-BitwiseXORExpression', 'Bitwise XOR expression')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_xor")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_xor_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_xor_assignment/index.html new file mode 100644 index 0000000000..7257e9cdb5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_xor_assignment/index.html @@ -0,0 +1,65 @@ +--- +title: 按位异或赋值 (^=) +slug: Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment +translation_of: Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment +--- +
{{jsSidebar("Operators")}}
+ +

按位异或赋值操作符 (^=) 使用二进制表示操作数,进行一次按位异或操作并赋值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-xor-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x ^= y
+Meaning:  x  = x ^ y
+ +

例子

+ +

使用按位异或赋值

+ +
let a = 5;      // 00000000000000000000000000000101
+a ^= 3;         // 00000000000000000000000000000011
+
+console.log(a); // 00000000000000000000000000000110
+// 6
+
+let b = 5;      // 00000000000000000000000000000101
+b ^= 0;         // 00000000000000000000000000000000
+
+console.log(b); // 00000000000000000000000000000101
+// 5
+
+
+
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_xor_assignment")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/class/index.html b/files/zh-cn/web/javascript/reference/operators/class/index.html new file mode 100644 index 0000000000..739c651513 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/class/index.html @@ -0,0 +1,112 @@ +--- +title: 类表达式 +slug: Web/JavaScript/Reference/Operators/class +tags: + - Class + - Classes + - ES6 +translation_of: Web/JavaScript/Reference/Operators/class +--- +
{{jsSidebar("Operators")}}
+ +

类表达式是用来定义类的一种语法。和函数表达式相同的一点是,类表达式可以是命名也可以是匿名的。如果是命名类表达式,这个名字只能在类体内部才能访问到。JavaScript 的类也是基于原型继承的。

+ +

语法

+ +
const MyClass = class [className] [extends] {
+  // class body
+};
+ +

描述

+ +

类表达式的语法和类语句的语法很类似,只是在类表达式中,你可以省略掉类名,而类语句中不能。

+ +

和类声明一样,类表达式中的代码也是强制严格模式的。

+ +

示例

+ +

使用类表达式

+ +

下面的代码使用类表达式语法创建了一个匿名类,然后赋值给变量 Foo。

+ +
let Foo = class {
+  constructor() {}
+  bar() {
+    return "Hello World!";
+  }
+};
+
+let instance = new Foo();
+instance.bar();
+// "Hello World!"
+
+ +

命名类表达式

+ +

如果你想在类体内部也能引用这个类本身,那么你就可以使用命名类表达式,并且这个类名只能在类体内部访问。

+ +
const Foo = class NamedFoo {
+  constructor() {}
+  whoIsThere() {
+    return NamedFoo.name;
+  }
+}
+
+let bar = new Foo();
+
+bar.whoIsThere();
+// "NamedFoo"
+
+NamedFoo.name;
+// ReferenceError: NamedFoo is not defined
+
+Foo.name;
+// "NamedFoo"
+
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ES2016', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2016')}}
{{SpecName('ES2017', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.class")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/comma_operator/index.html b/files/zh-cn/web/javascript/reference/operators/comma_operator/index.html new file mode 100644 index 0000000000..0636731b0b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/comma_operator/index.html @@ -0,0 +1,84 @@ +--- +title: 逗号操作符 +slug: Web/JavaScript/Reference/Operators/Comma_Operator +tags: + - comma operator + - 逗号操作符 +translation_of: Web/JavaScript/Reference/Operators/Comma_Operator +--- +
+
{{jsSidebar("Operators")}}
+
+ +

逗号操作符  对它的每个操作数求值(从左到右),并返回最后一个操作数的值。

+ +

{{EmbedInteractiveExample("pages/js/expressions-commaoperators.html")}}

+ +

语法

+ +
expr1, expr2, expr3...
+ +

参数

+ +
+
expr1, expr2, expr3...
+
任一表达式。
+
+ +

描述

+ +

当你想要在期望一个表达式的位置包含多个表达式时,可以使用逗号操作符。这个操作符最常用的一种情况是:for 循环中提供多个参数。

+ +

示例

+ +

假设 a 是一个二维数组,每一维度包含10个元素,则下面的代码使用逗号操作符一次递增/递减两个变量。需要注意的是,var 语句中的逗号不是逗号操作符,因为它不是存在于一个表达式中。尽管从实际效果来看,那个逗号同逗号运算符的表现很相似。但确切地说,它是 var 语句中的一个特殊符号,用于把多个变量声明结合成一个。下面的代码打印一个二维数组中斜线方向的元素:

+ +
for (var i = 0, j = 9; i <= 9; i++, j--)
+  document.writeln("a[" + i + "][" + j + "] = " + a[i][j]);
+ +

处理后返回

+ +

另一个使用逗号操作符的例子是在返回值前处理一些操作。如同下面的代码,只有最后一个表达式被返回,其他的都只是被求值。

+ +
function myFunc () {
+  var x = 0;
+
+  return (x += 1, x); // the same of return ++x;
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-11.14', 'Comma operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-comma-operator', 'Comma operator')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{Compat("javascript.operators.comma")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html b/files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html new file mode 100644 index 0000000000..d05ce68abd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html @@ -0,0 +1,277 @@ +--- +title: 比较操作符 +slug: Web/JavaScript/Reference/Operators/Comparison_Operators +tags: + - 严格比较操作符 + - 比较操作符 +translation_of: Web/JavaScript/Reference/Operators +--- +
{{jsSidebar("Operators")}}
+ +

JavaScript 有两种比较方式:严格比较运算符和转换类型比较运算符。对于严格比较运算符(===)来说,仅当两个操作数的类型相同且值相等为 true,而对于被广泛使用的比较运算符(==)来说,会在进行比较之前,将两个操作数转换成相同的类型。对于关系运算符(比如 <=)来说,会先将操作数转为原始值,使它们类型相同,再进行比较运算。

+ +

字符串比较则是使用基于标准字典的 Unicode 值来进行比较的。

+ +

比较的特点:

+ + + +

相等运算符

+ +

相等(==)

+ +

比较操作符会为两个不同类型的操作数转换类型,然后进行严格比较。当两个操作数都是对象时,JavaScript会比较其内部引用,当且仅当他们的引用指向内存中的相同对象(区域)时才相等,即他们在栈内存中的引用地址相同。

+ +

语法

+ +
x == y
+
+ +

例子

+ +
 1   ==  1     // true
+"1"  ==  1     // true
+ 1   == '1'    // true
+ 0   == false  // true
+
+ +

不相等 (!=)

+ +

不等操作符仅当操作数不相等时返回true,如果两操作数不是同一类型,JavaScript会尝试将其转为一个合适的类型,然后进行比较。如果两操作数为对象类型,JavaScript会比较其内部引用地址,仅当他们在内存中引用不同对象时不相等。

+ +

语法

+ +
x != y
+ +

例子

+ +
1 !=   2     // true
+1 !=  "1"    // false
+1 !=  '1'    // false
+1 !=  true   // false
+0 !=  false  // false
+
+ +

一致/严格相等 (===)

+ +

一致运算符不会进行类型转换,仅当操作数严格相等时返回true

+ +

语法

+ +
x === y
+ +

例子

+ +
3 === 3   // true
+3 === '3' // false
+var object1 = {"value":"key"}, object2={"value":"key"};
+object1 === object2 //false
+ +

不一致/严格不相等 (!==)

+ +

不一致运算符当操作数不相等或不同类型时返回true

+ +

语法

+ +
x !== y
+ +

例子

+ +
3 !== '3' // true
+4 !== 3   // true
+
+ +

关系运算符

+ +

大于运算符 (>)

+ +

大于运算符仅当左操作数大于右操作数时返回true

+ +

语法

+ +
x > y
+ +

例子

+ +
4 > 3 // true
+
+ +

大于等于运算符 (>=)

+ +

大于等于运算符当左操作数大于或等于右操作数时返回true

+ +

语法

+ +
 x >= y
+ +

例子

+ +
4 >= 3 // true
+3 >= 3 // true
+
+ +

小于运算符 (<)

+ +

小于运算符仅当左操作数小于右操作数时返回true

+ +

语法

+ +
 x < y
+ +

例子

+ +
3 < 4 // true
+
+ +

小于等于运算符 (<=)

+ +

小于等于运算符当左操作数小于或等于右操作数时返回true

+ +

语法

+ +
 x <= y
+ +

例子

+ +
3 <= 4 // true
+
+ +

使用比较操作符

+ +

标准相等操作符(== and !=) 使用 Abstract Equality Comparison Algorithm 去比较两个操作数。当两个操作数类型不相等时,会在比较前尝试将其转换为相同类型。 e.g., 对于表达式 5 == '5', 在比较前会先将右边字符串类型的操作数 5 转换为数字。

+ +

严格相等操作符 (=== and !==) 使用 Strict Equality Comparison Algorithm 并尝试对两个相同操作数进行相等比较,如果它们的类型不相等,那么永远会返回false 所以 5 !== '5'。

+ +

当需要明确操作数的类型和值的时候,或者操作数的确切类型非常重要时,应使用严格相等操作符。否则,当你允许操作数在比较前进行类型转换时,可以使用标准相等操作符来比较。

+ +

当比较运算涉及类型转换时 (i.e., non–strict comparison), JavaScript 会按以下规则对字符串,数字,布尔或对象类型的操作数进行操作:

+ + + +
注意: 字符串对象的类型是对象,不是字符串!字符串对象很少被使用,所以下面的结果也许会让你惊讶:
+ +
// true as both operands are Type String (i.e. string primitives):
+'foo' === 'foo'
+
+var a = new String('foo');
+var b = new String('foo');
+
+// false as a and b are Type Object and reference different objects
+a == b
+
+// false as a and b are Type Object and reference different objects
+a === b
+
+// true as a and 'foo' are of different type and, the Object (a)
+// is converted to String 'foo' before comparison
+a == 'foo' 
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.0
ECMAScript 3rd Edition.StandardAdds === and !== operators. Implemented in JavaScript 1.3
{{SpecName('ES5.1', '#sec-11.8', 'Relational Operators')}}
+ {{SpecName('ES5.1', '#sec-11.9', 'Equality Operators')}}
{{Spec2('ES5.1')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
{{SpecName('ES6', '#sec-relational-operators', 'Relational Operators')}}
+ {{SpecName('ES6', '#sec-equality-operators', 'Equality Operators')}}
{{Spec2('ES6')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
{{SpecName('ESDraft', '#sec-relational-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/conditional_operator/index.html b/files/zh-cn/web/javascript/reference/operators/conditional_operator/index.html new file mode 100644 index 0000000000..179496d7e3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/conditional_operator/index.html @@ -0,0 +1,126 @@ +--- +title: 条件运算符 +slug: Web/JavaScript/Reference/Operators/Conditional_Operator +tags: + - JavaScript + - Operator +translation_of: Web/JavaScript/Reference/Operators/Conditional_Operator +--- +
{{jsSidebar("Operators")}}
+ +

条件(三元)运算符是 JavaScript 仅有的使用三个操作数的运算符。一个条件后面会跟一个问号(?),如果条件为 {{Glossary("truthy")}} ,则问号后面的表达式A将会执行;表达式A后面跟着一个冒号(:),如果条件为 {{Glossary("falsy")}} ,则冒号后面的表达式B将会执行。本运算符经常作为 if 语句的简捷形式来使用。

+ +
{{EmbedInteractiveExample("pages/js/expressions-conditionaloperators.html")}}
+ + + +

语法

+ +
condition ? exprIfTrue : exprIfFalse
+ +

参数

+ +
+
condition
+
计算结果用作条件的表达式
+
exprIfTrue
+
如果表达式 condition 的计算结果是 {{Glossary("truthy")}}(它和 true 相等或者可以转换成 true ),那么表达式 exprIfTrue 将会被求值。
+
exprIfFalse
+
如果表达式 condition 的计算结果是 {{Glossary("falsy")}}(它可以转换成 false ),那么表达式 exprIfFalse 将会被执行。
+
+ +

描述

+ +

除了 false,可能的假值表达式还有:nullNaN 、 + 0 、空字符串( "" )、和 undefined 。如果 condition 是以上中的任何一个, 那么条件表达式的结果就是 exprIfFalse 表达式执行的结果。

+ +

一个简单的例子:

+ +
var age = 26;
+var beverage = (age >= 21) ? "Beer" : "Juice";
+console.log(beverage); // "Beer"
+
+ +

一个常见的用法是处理可能为 null 的值:

+ +
function greeting(person) {
+    var name = person ? person.name : "stranger";
+    return "Howdy, " + name;
+}
+
+console.log(greeting({name: 'Alice'}));  // "Howdy, Alice"
+console.log(greeting(null));             // "Howdy, stranger"
+
+ +
+

Note: The optional chaining operator 设计用来处理这种使用场景。在本文档写成的时候 (2019.01),这个运算符还处于实验阶段并且没有实现。

+
+ +

条件链

+ +

这个三元操作符是右结合的,也就是说你可以像这样把它链接起来, 和 if … else if … else if … else 链类似:

+
function example(…) {
+    return condition1 ? value1
+         : condition2 ? value2
+         : condition3 ? value3
+         : value4;
+}
+
+// Equivalent to:
+
+function example(…) {
+    if (condition1) { return value1; }
+    else if (condition2) { return value2; }
+    else if (condition3) { return value3; }
+    else { return value4; }
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.conditional")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/delete/index.html b/files/zh-cn/web/javascript/reference/operators/delete/index.html new file mode 100644 index 0000000000..ce03a46d29 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/delete/index.html @@ -0,0 +1,298 @@ +--- +title: delete 操作符 +slug: Web/JavaScript/Reference/Operators/delete +tags: + - JavaScript + - Operator + - Reference + - delete +translation_of: Web/JavaScript/Reference/Operators/delete +--- +
{{jsSidebar("Operators")}}
+ +

 delete 操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。

+ +
+
{{EmbedInteractiveExample("pages/js/expressions-deleteoperator.html")}}
+
+ + + +

语法

+ +
delete expression
+
+ +

 expression 的计算结果应该是某个属性的引用,例如:

+ +
delete object.property
+delete object['property']
+
+ +

参数

+ +
+
object
+
对象的名称,或计算结果为对象的表达式。
+
+ +
+
property
+
要删除的属性。
+
+ +

返回值

+ +

对于所有情况都是true,除非属性是一个{{jsxref("Object.hasOwnProperty", "自身的")}} {{jsxref("Errors/Cant_delete", "不可配置")}}的属性,在这种情况下,非严格模式返回 false

+ +

异常

+ +

严格模式下,如果是属性是一个自己不可配置的属性,会抛出{{jsxref("TypeError")}}。

+ +

描述

+ +

与通常的看法不同,delete操作符与直接释放内存无关。内存管理 通过断开引用来间接完成的,查看内存管理页可了解详情。

+ +

delete 操作符会从某个对象上移除指定属性。成功删除的时候会返回 true,否则返回 false

+ +

但是,以下情况需要重点考虑:

+ + + +

下面的代码块给出了一个简单的例子:

+ +
var Employee = {
+  age: 28,
+  name: 'abc',
+  designation: 'developer'
+}
+
+console.log(delete Employee.name);   // returns true
+console.log(delete Employee.age);    // returns true
+
+// 当试着删除一个不存在的属性时
+// 同样会返回true
+console.log(delete Employee.salary); // returns true
+ +

不可配置属性

+ +

当一个属性被设置为不可设置,delete操作将不会有任何效果,并且会返回false。在严格模式下会抛出语法错误({{jsxref("SyntaxError")}})。

+ +
var Employee = {};
+Object.defineProperty(Employee, 'name', {configurable: false});
+
+console.log(delete Employee.name);  // returns false
+ +

{{jsxref("Statements/var","var")}}, {{jsxref("Statements/let","let")}}以及{{jsxref("Statements/const","const")}}创建的不可设置的属性不能被delete操作删除。

+ +
var nameOther = 'XYZ';
+
+// 通过以下方法获取全局属性:
+Object.getOwnPropertyDescriptor(window, 'nameOther');
+
+// 输出: Object {value: "XYZ",
+//                  writable: true,
+//                  enumerable: true,
+//                  configurable: false}
+
+// 因为“nameOther”使用var关键词添加,
+// 它被设置为不可设置(non-configurable)
+delete nameOther;   // return false
+ +

在严格模式下,这样的操作会抛出异常。

+ +

严格模式与非严格模式的对比

+ +

在严格模式下,如果对一个变量的直接引用、函数的参数或者函数名使用delete操作,将会抛出语法错误({{jsxref("SyntaxError")}})。因此,为避免严格模式下的语法错误,必须以delete object.propertydelete object['property']的形式使用delete运算符。

+ +
Object.defineProperty(globalThis, 'variable1', { value: 10, configurable: true, });
+Object.defineProperty(globalThis, 'variable2', { value: 10, configurable: false, });
+
+console.log(delete variable1); // true
+
+// SyntaxError in strict mode.
+console.log(delete variable2); // false
+
+ +
function func(param) {
+  // SyntaxError in strict mode.
+  console.log(delete param); // false
+}
+
+// SyntaxError in strict mode.
+console.log(delete func); // false
+
+ +
+

下文在英文原版中已删除

+
+ +

任何使用var声明的变量都会被标记为不可设置的。在下面的例子中,salary是不可设置的以及不能被删除的。在非严格模式下,下面的delete操作将会返回false。

+ +
function Employee() {
+  delete salary;
+  var salary;
+}
+
+Employee();
+ +

让我们来看看相同的代码在严格模式下会有怎样的表现。会抛出一个语法错误( SyntaxError)而不是返回false。

+ +
"use strict";
+
+function Employee() {
+  delete salary;  // SyntaxError
+  var salary;
+}
+
+// 相似的,任何对任何函数
+// 直接使用delete操作将会抛出语法错误。
+
+function DemoFunction() {
+  //some code
+}
+
+delete DemoFunction; // SyntaxError
+ +

示例

+ +
// 在全局作用域创建 adminName 属性
+adminName = 'xyz';
+
+// 在全局作用域创建 empCount 属性
+// 因为我们使用了 var,它会标记为不可配置。同样 let 或 const 也是不可配置的。
+var empCount = 43;
+
+EmployeeDetails = {
+  name: 'xyz',
+  age: 5,
+  designation: 'Developer'
+};
+
+// adminName 是全局作用域的一个属性。
+// 因为它不是用 var 创建的,所在可以删除。
+// 因此,它是可配置的。
+delete adminName;       // 返回 true
+
+// 相反,empCount 是不可配置的,
+// 因为创建它时使用了 var。
+delete empCount;       // 返回 false
+
+// delete 可用于删除对象的属性
+delete EmployeeDetails.name; // 返回 true
+
+// 甚至属性不存在,它也会返回 "true"
+delete EmployeeDetails.salary; // 返回 true
+
+// delete 对内建静态属性不起作用
+delete Math.PI; // 返回 false
+
+// EmployeeDetails 是全局作用域的一个属性。
+// 因为定义它的时候没有使用 "var",它被标记为可配置。
+delete EmployeeDetails;   // 返回 true
+
+function f() {
+  var z = 44;
+
+  // delete 对局部变量名不起作用
+  delete z;     // 返回 false
+}
+ +

delete 和原型链

+ +

在下面的示例中,我们删除一个对象的自己的属性,而原型链上具有相同名称的属性可用:

+ +
function Foo() {
+  this.bar = 10;
+}
+
+Foo.prototype.bar = 42;
+
+var foo = new Foo();
+
+// 返回 true,因为删除的是 foo 对象的自身属性
+delete foo.bar;
+
+// foo.bar 仍然可用,因为它在原型链上可用。
+console.log(foo.bar);   //42
+
+// 从原型上删除属性
+delete Foo.prototype.bar; //true
+
+// 由于已删除“ bar”属性,因此不能再从Foo继承它。
+console.log(foo.bar);    //undefined
+
+ +

删除数组元素

+ +

当你删除一个数组元素时,数组的长度不受影响。即便你删除了数组的最后一个元素也是如此。

+ +

当用 delete 操作符删除一个数组元素时,被删除的元素已经不再属于该数组。下面的例子中用 delete 删除了 trees[3]

+ +
var trees = ["redwood","bay","cedar","oak","maple"];
+delete trees[3];
+if (3 in trees) {
+   // 这里不会执行
+}
+
+ +

如果你想让一个数组元素继续存在但是其值是 undefined,那么可以使用将 undefined 赋值给这个元素而不是使用 delete。下面的例子中,trees[3] 被赋值为 undefined,但该元素仍然存在。

+ +
var trees = ["redwood","bay","cedar","oak","maple"];
+trees[3] = undefined;
+if (3 in trees) {
+   // 这里会被执行
+}
+ +

如果你想通过改变数组的内容来移除一个数组元素,请使用{{jsxref("Array.splice()", "splice()")}} 方法。在下面的例子中,通过使用{{jsxref("Array.splice()", "splice()")}},将trees[3]从数组中移除。

+ +
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
+trees.splice(3,1);
+console.log(trees); // ["redwood", "bay", "cedar", "maple"]
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-delete-operator', 'The delete Operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.delete")}}

+ +

跨浏览器提示

+ +

尽管ECMAScript使得对象的迭代顺序依赖于实现,但似乎所有主流浏览器都支持基于最早添加的属性(至少对于不在原型上的属性)的迭代顺序(译注:ES5 标准取消了属性遍历的顺序的规定)。但是,在 IE 中,使用 delete 删除一个属性后,奇怪的事情发生了。在IE中,如果被删除的属性重新被添加,那么遍历时,该属性的顺序会在上次删除前的那个位置,而不是出现在遍历的最后一个。

+ +

如果您想在跨浏览器的环境中使用有序的关联数组,请使用{{jsxref("Map")}}对象(如果有),或使用两个单独的数组来模拟(一个用于键,另一个用于 值),或者建立一个由单一属性对象组成的数组等。

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/destructuring_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/destructuring_assignment/index.html new file mode 100644 index 0000000000..39d57a75d7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/destructuring_assignment/index.html @@ -0,0 +1,431 @@ +--- +title: 解构赋值 +slug: Web/JavaScript/Reference/Operators/Destructuring_assignment +tags: + - ECMAScript 2015 + - JavaScript + - 对象 + - 操作符 + - 数组 + - 结构 + - 赋值 +translation_of: Web/JavaScript/Reference/Operators/Destructuring_assignment +--- +
{{jsSidebar("Operators")}}
+ +

解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。

+ +

{{EmbedInteractiveExample("pages/js/expressions-destructuringassignment.html")}}

+ + + +

语法

+ +
var a, b, rest;
+[a, b] = [10, 20];
+console.log(a); // 10
+console.log(b); // 20
+
+[a, b, ...rest] = [10, 20, 30, 40, 50];
+console.log(a); // 10
+console.log(b); // 20
+console.log(rest); // [30, 40, 50]
+
+({ a, b } = { a: 10, b: 20 });
+console.log(a); // 10
+console.log(b); // 20
+
+
+// Stage 4(已完成)提案中的特性
+({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
+console.log(a); // 10
+console.log(b); // 20
+console.log(rest); // {c: 30, d: 40}
+
+ +

描述

+ +

对象和数组逐个对应表达式,或称对象字面量和数组字面量,提供了一种简单的定义一个特定的数据组的方法。

+ +
var x = [1, 2, 3, 4, 5];
+ +

解构赋值使用了相同的语法,不同的是在表达式左边定义了要从原变量中取出什么变量。

+ +
var x = [1, 2, 3, 4, 5];
+var [y, z] = x;
+console.log(y); // 1
+console.log(z); // 2
+
+ +

JavaScript 中,解构赋值的作用类似于 Perl 和 Python 语言中的相似特性。

+ +

解构数组

+ +

变量声明并赋值时的解构

+ +
var foo = ["one", "two", "three"];
+
+var [one, two, three] = foo;
+console.log(one); // "one"
+console.log(two); // "two"
+console.log(three); // "three"
+ +

变量先声明后赋值时的解构

+ +

通过解构分离变量的声明,可以为一个变量赋值。

+ +
var a, b;
+
+[a, b] = [1, 2];
+console.log(a); // 1
+console.log(b); // 2
+ +

默认值

+ +

为了防止从数组中取出一个值为undefined的对象,可以在表达式左边的数组中为任意对象预设默认值。

+ +
var a, b;
+
+[a=5, b=7] = [1];
+console.log(a); // 1
+console.log(b); // 7
+ +

交换变量

+ +

在一个解构表达式中可以交换两个变量的值。

+ +

没有解构赋值的情况下,交换两个变量需要一个临时变量(或者用低级语言中的XOR-swap技巧)。

+ +
var a = 1;
+var b = 3;
+
+[a, b] = [b, a];
+console.log(a); // 3
+console.log(b); // 1
+ +

解析一个从函数返回的数组

+ +

从一个函数返回一个数组是十分常见的情况。解构使得处理返回值为数组时更加方便。

+ +

在下面例子中,要让 [1, 2] 成为函数的 f() 的输出值,可以使用解构在一行内完成解析。

+ +
function f() {
+  return [1, 2];
+}
+
+var a, b;
+[a, b] = f();
+console.log(a); // 1
+console.log(b); // 2
+
+ +

忽略某些返回值

+ +

你也可以忽略你不感兴趣的返回值:

+ +
function f() {
+  return [1, 2, 3];
+}
+
+var [a, , b] = f();
+console.log(a); // 1
+console.log(b); // 3
+ +

你也可以忽略全部返回值:

+ +
[,,] = f();
+
+ +

将剩余数组赋值给一个变量

+ +

当解构一个数组时,可以使用剩余模式,将数组剩余部分赋值给一个变量。

+ +
var [a, ...b] = [1, 2, 3];
+console.log(a); // 1
+console.log(b); // [2, 3]
+ +

注意:如果剩余元素右侧有逗号,会抛出 {{jsxref("SyntaxError")}},因为剩余元素必须是数组的最后一个元素。

+ +
var [a, ...b,] = [1, 2, 3];
+// SyntaxError: rest element may not have a trailing comma
+ +

用正则表达式匹配提取值

+ +

用正则表达式的 exec() 方法匹配字符串会返回一个数组,该数组第一个值是完全匹配正则表达式的字符串,然后的值是匹配正则表达式括号内内容部分。解构赋值允许你轻易地提取出需要的部分,忽略完全匹配的字符串——如果不需要的话。

+ +
function parseProtocol(url) {
+  var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
+  if (!parsedURL) {
+    return false;
+  }
+  console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]
+
+  var [, protocol, fullhost, fullpath] = parsedURL;
+  return protocol;
+}
+
+console.log(parseProtocol('https://developer.mozilla.org/en-US/Web/JavaScript')); // "https"
+
+ +

解构对象

+ +

基本赋值

+ +
var o = {p: 42, q: true};
+var {p, q} = o;
+
+console.log(p); // 42
+console.log(q); // true
+
+ +

无声明赋值

+ +

一个变量可以独立于其声明进行解构赋值。

+ +
var a, b;
+
+({a, b} = {a: 1, b: 2});
+
+ +
+

注意:赋值语句周围的圆括号 ( ... ) 在使用对象字面量无声明解构赋值时是必须的。

+ +

{a, b} = {a: 1, b: 2} 不是有效的独立语法,因为左边的 {a, b} 被认为是一个块而不是对象字面量。

+ +

然而,({a, b} = {a: 1, b: 2}) 是有效的,正如 var {a, b} = {a: 1, b: 2}

+ +

你的 ( ... ) 表达式之前需要有一个分号,否则它可能会被当成上一行中的函数执行。

+
+ +

给新的变量名赋值

+ +

可以从一个对象中提取变量并赋值给和对象属性名不同的新的变量名。

+ +
var o = {p: 42, q: true};
+var {p: foo, q: bar} = o;
+
+console.log(foo); // 42
+console.log(bar); // true 
+ +

默认值

+ +

变量可以先赋予默认值。当要提取的对象没有对应的属性,变量就被赋予默认值。

+ +
var {a = 10, b = 5} = {a: 3};
+
+console.log(a); // 3
+console.log(b); // 5
+
+ +

给新的变量命名并提供默认值

+ +

一个属性可以同时 1)从一个对象解构,并分配给一个不同名称的变量 2)分配一个默认值,以防未解构的值是 undefined

+ +
var {a:aa = 10, b:bb = 5} = {a: 3};
+
+console.log(aa); // 3
+console.log(bb); // 5
+
+ +

函数参数默认值

+ +

ES5 版本

+ +
function drawES5Chart(options) {
+  options = options === undefined ? {} : options;
+  var size = options.size === undefined ? 'big' : options.size;
+  var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords;
+  var radius = options.radius === undefined ? 25 : options.radius;
+  console.log(size, cords, radius);
+  // now finally do some chart drawing
+}
+
+drawES5Chart({
+  cords: { x: 18, y: 30 },
+  radius: 30
+});
+ +

ES2015 版本

+ +
function drawES2015Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {})
+{
+  console.log(size, cords, radius);
+  // do some chart drawing
+}
+
+drawES2015Chart({
+  cords: { x: 18, y: 30 },
+  radius: 30
+});
+ +
+

在上面的 drawES2015Chart 的函数签名中,解构的左手边被分配给右手边的空对象字面值:{size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}。你也可以在没有右侧分配的情况下编写函数。但是,如果你忽略了右边的赋值,那么函数会在被调用的时候查找至少一个被提供的参数,而在当前的形式下,你可以直接调用 drawES2015Chart() 而不提供任何参数。如果你希望能够在不提供任何参数的情况下调用该函数,则当前的设计非常有用,而另一种方法在您确保将对象传递给函数时非常有用。

+
+ +

解构嵌套对象和数组

+ +
const metadata = {
+  title: 'Scratchpad',
+  translations: [
+    {
+      locale: 'de',
+      localization_tags: [],
+      last_edit: '2014-04-14T08:43:37',
+      url: '/de/docs/Tools/Scratchpad',
+      title: 'JavaScript-Umgebung'
+    }
+  ],
+  url: '/en-US/docs/Tools/Scratchpad'
+};
+
+let {
+  title: englishTitle, // rename
+  translations: [
+    {
+       title: localeTitle, // rename
+    },
+  ],
+} = metadata;
+
+console.log(englishTitle); // "Scratchpad"
+console.log(localeTitle);  // "JavaScript-Umgebung"
+ +

For of 迭代和解构

+ +
var people = [
+  {
+    name: 'Mike Smith',
+    family: {
+      mother: 'Jane Smith',
+      father: 'Harry Smith',
+      sister: 'Samantha Smith'
+    },
+    age: 35
+  },
+  {
+    name: 'Tom Jones',
+    family: {
+      mother: 'Norah Jones',
+      father: 'Richard Jones',
+      brother: 'Howard Jones'
+    },
+    age: 25
+  }
+];
+
+for (var {name: n, family: {father: f}} of people) {
+  console.log('Name: ' + n + ', Father: ' + f);
+}
+
+// "Name: Mike Smith, Father: Harry Smith"
+// "Name: Tom Jones, Father: Richard Jones"
+ +

从作为函数实参的对象中提取数据

+ +
function userId({id}) {
+  return id;
+}
+
+function whois({displayName: displayName, fullName: {firstName: name}}){
+  console.log(displayName + " is " + name);
+}
+
+var user = {
+  id: 42,
+  displayName: "jdoe",
+  fullName: {
+      firstName: "John",
+      lastName: "Doe"
+  }
+};
+
+console.log("userId: " + userId(user)); // "userId: 42"
+whois(user); // "jdoe is John"
+ +

这段代码从user对象中提取并输出iddisplayName 和 firstName

+ +

对象属性计算名和解构

+ +

计算属性名,如 object literals,可以被解构。

+ +
let key = "z";
+let { [key]: foo } = { z: "bar" };
+
+console.log(foo); // "bar"
+
+ +

对象解构中的 Rest

+ +

Rest/Spread Properties for ECMAScript 提案(阶段 4)将 rest 语法添加到解构中。Rest 属性收集那些尚未被解构模式拾取的剩余可枚举属性键。

+ +
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
+a; // 10
+b; // 20
+rest; // { c: 30, d: 40 }
+ +

无效的 JavaScript 标识符作为属性名称

+ +

通过提供有效的替代标识符,解构可以与不是有效的JavaScript标识符的属性名称一起使用。

+ +
const foo = { 'fizz-buzz': true };
+const { 'fizz-buzz': fizzBuzz } = foo;
+
+console.log(fizzBuzz); // "true"
+
+ +

解构对象时会查找原型链(如果属性不在对象自身,将从原型链中查找)

+ +
// 声明对象 和 自身 self 属性
+var obj = {self: '123'};
+// 在原型链中定义一个属性 prot
+obj.__proto__.prot = '456';
+// test
+const {self, prot} = obj;
+// self "123"
+// prot "456"(访问到了原型链)
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-destructuring-assignment', 'Destructuring assignment')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-destructuring-assignment', 'Destructuring assignment')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.destructuring")}}

+ +

相关链接

+ + + +

译者注:关于 42

+ +

为什么在示例代码中出现了那么多 42?如果有什么特别的原因的话,以下是译者的猜测。

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/division/index.html b/files/zh-cn/web/javascript/reference/operators/division/index.html new file mode 100644 index 0000000000..8bfc53db1f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/division/index.html @@ -0,0 +1,76 @@ +--- +title: 除法 (/) +slug: Web/JavaScript/Reference/Operators/Division +tags: + - JavaScript + - 参考 + - 语言特征 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Division +--- +
{{jsSidebar("Operators")}}
+ +

除法运算符 (/) 计算了两个操作数的商,左边的数是被除数,右边的是除数

+ +
{{EmbedInteractiveExample("pages/js/expressions-division.html")}}
+ +
+ + + +

语法

+ +
Operator: x / y
+
+ +

例子

+ +

基本除法

+ +
1 / 2              // 0.5
+
+Math.floor(3 / 2) // 1
+
+1.0 / 2.0         // 0.5
+
+ +

除以0

+ +
2.0 / 0     // Infinity
+
+2.0 / 0.0   // Infinity, because 0.0 === 0
+
+2.0 / -0.0  // -Infinity
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Division operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.division")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/division_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/division_assignment/index.html new file mode 100644 index 0000000000..25f93e997b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/division_assignment/index.html @@ -0,0 +1,58 @@ +--- +title: Division assignment (/=) +slug: Web/JavaScript/Reference/Operators/Division_assignment +translation_of: Web/JavaScript/Reference/Operators/Division_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The division assignment operator (/=) divides a variable by the value of the right operand and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-division-assignment.html")}}
+ + + +

语法

+ +
Operator: x /= y
+Meaning:  x  = x / y
+ +

Examples

+ +

Using division assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar /= 2     // 2.5
+bar /= 'foo' // NaN
+bar /= 0     // Infinity
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.division_assignment")}}

+ +

See also

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/exponentiation/index.html b/files/zh-cn/web/javascript/reference/operators/exponentiation/index.html new file mode 100644 index 0000000000..e9299d7f8f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/exponentiation/index.html @@ -0,0 +1,107 @@ +--- +title: 求幂 (**) +slug: Web/JavaScript/Reference/Operators/Exponentiation +tags: + - JavaScript + - 参考 + - 语言特征 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Exponentiation +--- +
{{jsSidebar("Operators")}}
+ +

求幂运算符(**)返回将第一个操作数加到第二个操作数的幂的结果。它等效于Math.pow,不同之处在于它也接受BigInts作为操作数。

+ +
{{EmbedInteractiveExample("pages/js/expressions-exponentiation.html")}}
+ + + +

语法

+ +
Operator: var1 ** var2
+
+ +

简介

+ +

求幂运算符是是右结合的a ** b ** c 等于 a ** (b ** c).

+ +

在大多数语言里,比如PHP、Python等那些有一个幂运算符 (**) 的语言,幂运算符被定义有一个比一元运算符,比如一元的 + 和一元的 - 更高的运算顺序,但有一些例外。在Bash语言里,** 运算符被定义有一个比一元运算符更低的运算顺序。

+ +

在JavaScript里,你不可能写出一个不明确的求幂表达式。这就是说,你不能立刻将一个一元运算符(+/-/~/!/delete/void/typeof)放在基数前,这样做只会导致一个语法错误。

+ +
-2 ** 2;
+// 4 in Bash, -4 in other languages.
+// This is invalid in JavaScript, as the operation is ambiguous.
+
+
+-(2 ** 2);
+// -4 in JavaScript and the author's intention is unambiguous.
+
+ +

注意有些编程语言用扬抑符 ^ 做乘方运算,但是JavaScript将这个符号作为了XOR位逻辑运算符

+ +

例子

+ +

基本求幂

+ +
2 ** 3   // 8
+3 ** 2   // 9
+3 ** 2.5 // 15.588457268119896
+10 ** -1 // 0.1
+NaN ** 2 // NaN
+
+ +

结合

+ +
2 ** 3 ** 2   // 512
+2 ** (3 ** 2) // 512
+(2 ** 3) ** 2 // 64
+ +

与一元运算符的用法

+ +

取求幂表达式的值的相反数:

+ +
-(2 ** 2) // -4
+
+ +

将求幂表达式的底数转化为一个负数:

+ +
(-2) ** 2 // 4
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-exp-operator', 'Exponentiation operator')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.operators.exponentiation")}}

+ +

See also

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/exponentiation_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/exponentiation_assignment/index.html new file mode 100644 index 0000000000..12f77694c7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/exponentiation_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: Exponentiation assignment (**=) +slug: Web/JavaScript/Reference/Operators/Exponentiation_assignment +translation_of: Web/JavaScript/Reference/Operators/Exponentiation_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The exponentiation assignment operator (**=) raises the value of a variable to the power of the right operand.

+ +
{{EmbedInteractiveExample("pages/js/expressions-exponentiation-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x **= y
+Meaning:  x  = x ** y
+ +

Examples

+ +

Using exponentiation assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar **= 2     // 25
+bar **= 'foo' // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.exponentiation_assignment")}}

+ +

See also

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/expression_closures/index.html b/files/zh-cn/web/javascript/reference/operators/expression_closures/index.html new file mode 100644 index 0000000000..e5dee577bc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/expression_closures/index.html @@ -0,0 +1,76 @@ +--- +title: Expression closures +slug: Web/JavaScript/Reference/Operators/Expression_closures +tags: + - Functions + - JavaScript + - Reference +translation_of: Archive/Web/JavaScript/Expression_closures +--- +
非标准,不要使用!
+闭包表达式语法是废弃的 SpiderMonkey 的特性,并且将被移除。为了长远使用,考虑使用箭头函数
+ +
{{jsSidebar("Operators")}}
+ +

表达式闭包是定义简单函数的一种便捷方式。

+ +

语法

+ +
function [name]([param1[, param2[, ..., paramN]]])
+   expression
+
+ +

参数

+ +
+
name
+
函数名。函数名可以省略不写,称为匿名函数。函数名仅在函数体有效。
+
paramN
+
形参名。一个函数最多可以有255个参数。
+
expression
+
构成函数体的表达式。
+
+ +

描述

+ +

这一附加特性只是编写简单函数的快捷方式,让语言更类似通常的 Lambda 标记

+ +

JavaScript 1.7 及之前版本:

+ +
function(x) { return x * x; }
+ +

JavaScript 1.8:

+ +
function(x) x * x
+ +

该语法支持省略花括号和'return'语句。使用这种编码的目的只是为了在句法上使得代码更加简化,但除此之外没有其他好处。

+ +

示例

+ +

一种绑定事件监听器的便捷方式:

+ +
 document.addEventListener("click", function() false, true);
+
+ +

在 JavaScript 1.6 中的一些数组函数中使用该标记:

+ +
elems.some(function(elem) elem.type == "text");
+
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.expression_closures")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/function/index.html b/files/zh-cn/web/javascript/reference/operators/function/index.html new file mode 100644 index 0000000000..73939d3da0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/function/index.html @@ -0,0 +1,182 @@ +--- +title: 函数表达式 +slug: Web/JavaScript/Reference/Operators/function +tags: + - Function + - JavaScript + - 函数 + - 基本表达式 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/function +--- +
{{jsSidebar("Operators")}}
+ +

function 关键字可以用来在一个表达式中定义一个函数。

+ +

你也可以使用 Function 构造函数和一个函数声明来定义函数。

+ +

语法

+ +
let function_expression = function [name]([param1[, param2[, ..., paramN]]]) {
+   statements
+};
+ +

ES2015开始,你也可以使用箭头函数

+ +

参数

+ +
+
name
+
函数名称。可被省略,此种情况下的函数是匿名函数(anonymous)。 函数名称只是函数体中的一个本地变量。
+
paramN
+
被传递给函数的一个参数名称。一个函数至多拥有 255 个参数。
+
statements
+
构成函数体的语句。
+
+ +

描述

+ +

函数表达式(function expression)非常类似于函数声明(function statement)(详情查看函数声明,并且两者拥有几乎相同的语法。函数表达式与函数声明的最主要区别是函数名称(function name),在函数表达式中可省略它,从而创建匿名函数(anonymous functions)。一个函数表达式可以被用作一个IIFE(Immediately Invoked Function Expression,即时调用的函数表达式),它一旦定义就运行。更多信息请查看函数

+ +

 函数表达式提升 (Function expression hoisting)

+ +

JavaScript中的函数表达式没有提升,不像函数声明,你在定义函数表达式之前不能使用函数表达式:

+ +
 notHoisted(); // TypeError: notHoisted is not a function
+
+var notHoisted = function() {
+   console.log('bar');
+};
+ +

命名函数表达式(Named function expression)

+ +

如果你想在函数体内部引用当前函数,则需要创建一个命名函数表达式。然后函数名称将会(且只会)作为函数体(作用域内)的本地变量。这样也可以避免使用非标准的 arguments.callee 属性。

+ +
var math = {
+  'factorial': function factorial(n) {
+    if (n <= 1)
+      return 1;
+    return n * factorial(n - 1);
+  }
+};
+
+ +

被函数表达式赋值的那个变量会有一个name属性,如果你把这个变量赋值给另一个变量的话,这个name属性的值也不会改变。如果函数是一个匿名函数,那name属性的值就是被赋值的变量的名称(隐藏值)。如果函数不是匿名的话,那name属性的值就是这个函数的名称(显性值)。这对于箭头函数也同样适用(箭头函数没有名字,所以你只能赋予name属性一个隐性名)。

+ +
var foo = function() {}
+foo.name // "foo"
+
+var foo2 = foo
+foo2.name // "foo"
+
+var bar = function baz() {}
+bar.name // "baz"
+
+console.log(foo === foo2); //true
+console.log(typeof baz);// undefined
+console.log(bar === baz); // false (errors because baz == undefined)
+
+ +

示例

+ +

下面的例子定义了一个匿名函数并把它赋值给变量x。这个函数返回它参数的平方:

+ +
var x = function(y) {
+   return y * y;
+};
+ +

更多情况下被当作回调函数使用:

+ +
button.addEventListener('click', function(event) {
+    console.log('button is clicked!')
+})
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES3', '#sec-13', 'Function definition')}}Standard初始定义。JavaScript 1.5 实现。
{{SpecName('ES5.1', '#sec-13', 'Function definition')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-function-definitions', 'Function defintions')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/function_star_/index.html b/files/zh-cn/web/javascript/reference/operators/function_star_/index.html new file mode 100644 index 0000000000..1f607de5d9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/function_star_/index.html @@ -0,0 +1,89 @@ +--- +title: function* 表达式 +slug: Web/JavaScript/Reference/Operators/function* +tags: + - ECMAScript 2015 + - Function + - Iterator + - JavaScript + - Operator + - Primary Expression +translation_of: Web/JavaScript/Reference/Operators/function* +--- +
{{jsSidebar("Operators")}}
+ +

function*关键字可以在表达式内部定义一个生成器函数。

+ +

{{EmbedInteractiveExample("pages/js/expressions-functionasteriskexpression.html")}}

+ +

语法

+ +
function* [name]([param1[, param2[, ..., paramN]]]) {
+   statements
+}
+ +

参数

+ +
+
name
+
函数名。在声明匿名函数时可以省略。函数名称只是函数体中的一个本地变量。
+
paramN
+
传入函数的一个参数名。一个函数最多有 255 个参数。
+
statements
+
函数体。
+
+ +

描述

+ +

function*表达式和{{jsxref('Statements/function*', 'function* 声明')}}比较相似,并具有几乎相同的语法。function*表达式和function*声明之间主要区别就是函数名,即在创建匿名函数时,function*表达式可以省略函数名。阅读{{jsxref('Function', '函数')}}章节了解更多信息。

+ +

示例

+ +

下面的示例定义了一个未命名的生成器函数并把它赋值给x。函数产出它的传入参数的平方:

+ +
var x = function*(y) {
+   yield y * y;
+};
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#', 'function*')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#', 'function*')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.function_star")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html b/files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html new file mode 100644 index 0000000000..1442d50019 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html @@ -0,0 +1,193 @@ +--- +title: Generator推导式 +slug: Web/JavaScript/Reference/Operators/Generator_comprehensions +translation_of: Archive/Web/JavaScript/Generator_comprehensions +--- +
非标准的。不要使用!
+generator推导式是非标准的,而且它不太可能会被添加到ECMAScript。考虑到将来,请使用 {{jsxref("Statements/function*", "generator", "", 1)}}。 +

 

+
+ +

{{jsSidebar("Operators")}}

+ +

生成器推导语法是一种JavaScript表达式,它允许您基于现有的可迭代对象快速组合新的生成器函数。

+ +

许多编程语言中都存在推导。

+ +

看下面,原来Generator推导式语法在SpiderMonkey的不同之处,它是基于对ECMAScript4的提议。

+ +

语法

+ +
(for (x of iterable) x)
+(for (x of iterable) if (condition) x)
+(for (x of iterable) for (y of iterable) x + y)
+
+ +

描述

+ +

在Generator推导式中,这两种构成方式都是允许的:

+ + + +

for-of迭代器是构成的第一个部分。当由多重部分构成时,后面for-of和if构成方式都是被允许的。

+ +

示例

+ +

单个构成部分的 generator推导式:

+ +
(for (i of [ 1, 2, 3 ]) i*i );
+// generator function which yields 1, 4, and 9
+
+[...(for (i of [ 1, 2, 3 ]) i*i )];
+// [1, 4, 9]
+
+var abc = [ "A", "B", "C" ];
+(for (letters of abc) letters.toLowerCase());
+// generator function which yields "a", "b", and "c"
+
+
+ +

有if伴随的多重构成的gennerator推导式:

+ +
var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
+
+(for (year of years) if (year > 2000) year);
+// generator function which yields 2006, 2010, and 2014
+
+(for (year of years) if (year > 2000) if(year < 2010) year);
+// generator function which yields 2006, the same as below:
+
+(for (year of years) if (year > 2000 && year < 2010) year);
+// generator function which yields 2006
+
+ +

Generator推导式与Generator函数对比

+ +

用一种简单的方式来理解generator推导式的语法并与generator函数来做个比较。

+ +

Example 1: 仅是 generator.

+ +
var numbers = [ 1, 2, 3 ];
+
+// Generator 函数
+(function*() {
+  for (let i of numbers) {
+    yield i * i;
+  }
+})()
+
+// Generator 推导式
+(for (i of numbers) i*i );
+
+// 结果: 两者都得到 yields [ 1, 4, 9 ]
+
+ +

Example 2: 在 generator 中用if.

+ +
var numbers = [ 1, 2, 3 ];
+
+// Generator 函数
+(function*() {
+  for (let i of numbers) {
+    if (i < 3) {
+      yield i * 1;
+    }
+  }
+})()
+
+// Generator 推导式
+(for (i of numbers) if (i < 3) i);
+
+// 结果: 两者都得到 yields [ 1, 2 ]
+ +

规范

+ +

Generator推导式是最初在ECMAScript 2015中进行拟稿,但是在14年8月27号修订中被移除了。 请参阅较旧版本的ES2015规范语义.

+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{ CompatGeckoDesktop("30") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile("30") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

SpiderMonkey的具体实现笔记

+ + + +

与旧的JS1.7 / JS1.8理解的区别

+ + + +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/greater_than/index.html b/files/zh-cn/web/javascript/reference/operators/greater_than/index.html new file mode 100644 index 0000000000..afb4a2d134 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/greater_than/index.html @@ -0,0 +1,95 @@ +--- +title: 大于运算符 (>) +slug: Web/JavaScript/Reference/Operators/Greater_than +translation_of: Web/JavaScript/Reference/Operators/Greater_than +--- +
{{jsSidebar("Operators")}}
+ +

当左边操作数大于右边的时候,大于(>) 运算符返回true,否则返回false

+ +
{{EmbedInteractiveExample("pages/js/expressions-greater-than.html")}}
+ + + +

语法

+ +
x > y
+ +

描述

+ +

操作数之间按照 Abstract Relational Comparison 算法进行比较。进一步了解该算法,请参考 小于 运算符的相关文档.

+ +

例子

+ +

字符串的比较

+ +
console.log("a" > "b");        // false
+console.log("a" > "a");        // false
+console.log("a" > "3");        // true
+ +

字符串和数字的比较

+ +
console.log("5" > 3);          // true
+console.log("3" > 3);          // false
+console.log("3" > 5);          // false
+
+console.log("hello" > 5);      // false
+console.log(5 > "hello");      // false
+
+console.log("5" > 3n);         // true
+console.log("3" > 5n);         // false
+ +

数字间的比较

+ +
console.log(5 > 3);            // true
+console.log(3 > 3);            // false
+console.log(3 > 5);            // false
+ +

数字和 BigInt 数据的比较

+ +
console.log(5n > 3);           // true
+console.log(3 > 5n);           // false
+ +

Boolean, null, undefined, NaN的比较

+ +
console.log(true > false);     // true
+console.log(false > true);     // false
+
+console.log(true > 0);         // true
+console.log(true > 1);         // false
+
+console.log(null > 0);         // false
+console.log(1 > null);         // true
+
+console.log(undefined > 3);    // false
+console.log(3 > undefined);    // false
+
+console.log(3 > NaN);          // false
+console.log(NaN > 3);          // false
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.greater_than")}}

+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/greater_than_or_equal/index.html b/files/zh-cn/web/javascript/reference/operators/greater_than_or_equal/index.html new file mode 100644 index 0000000000..9fa5b48436 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/greater_than_or_equal/index.html @@ -0,0 +1,95 @@ +--- +title: 大于或等于 +slug: Web/JavaScript/Reference/Operators/Greater_than_or_equal +translation_of: Web/JavaScript/Reference/Operators/Greater_than_or_equal +--- +
{{jsSidebar("Operators")}}
+ +

The greater than or equal operator (>=) returns true if the left operand is greater than or equal to the right operand, and false otherwise.

+ +
{{EmbedInteractiveExample("pages/js/expressions-greater-than-or-equal.html")}}
+ + + +

Syntax

+ +
 x >= y
+ +

Description

+ +

The operands are compared using the Abstract Relational Comparison algorithm. See the documentation for the Less than operator for a summary of this algorithm.

+ +

Examples

+ +

String to string comparison

+ +
console.log("a" >= "b");     // false
+console.log("a" >= "a");     // true
+console.log("a" >= "3");     // true
+
+ +

String to number comparison

+ +
console.log("5" >= 3);       // true
+console.log("3" >= 3);       // true
+console.log("3" >= 5);       // false
+
+console.log("hello" >= 5);   // false
+console.log(5 >= "hello");   // false
+ +

Number to Number comparison

+ +
console.log(5 >= 3);         // true
+console.log(3 >= 3);         // true
+console.log(3 >= 5);         // false
+ +

Number to BigInt comparison

+ +
console.log(5n >= 3);        // true
+console.log(3 >= 3n);        // true
+console.log(3 >= 5n);        // false
+ +

Comparing Boolean, null, undefined, NaN

+ +
console.log(true >= false);  // true
+console.log(true >= true);   // true
+console.log(false >= true);  // false
+
+console.log(true >= 0);      // true
+console.log(true >= 1);      // true
+
+console.log(null >= 0);      // true
+console.log(1 >= null);      // true
+
+console.log(undefined >= 3); // false
+console.log(3 >= undefined); // false
+
+console.log(3 >= NaN);       // false
+console.log(NaN >= 3);       // false
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.greater_than_or_equal")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/grouping/index.html b/files/zh-cn/web/javascript/reference/operators/grouping/index.html new file mode 100644 index 0000000000..837cdf366f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/grouping/index.html @@ -0,0 +1,93 @@ +--- +title: 圆括号运算符 +slug: Web/JavaScript/Reference/Operators/Grouping +tags: + - JavaScript + - Operator + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/Grouping +--- +
{{jsSidebar("Operators")}}
+ +

圆括号运算符 ( ) 用于控制表达式中的运算优先级。

+ +
{{EmbedInteractiveExample("pages/js/expressions-groupingoperator.html")}}
+ + + +

语法

+ +

译者:下列语法是 MDN 上已知的最简单的之一。

+ +
 ( )
+ +

说明

+ +

圆括号运算符由一对圆括号组成,包裹表达式和子表达式用来覆盖常规的运算符优先级,达到低优先级的表达式比高优先级的表达式更早运算。

+ +

示例

+ +

下面的代码展示了加法运算先于乘法运算的情况。

+ +
var a = 1;
+var b = 2;
+var c = 3;
+
+// default precedence
+a + b * c     // 7
+// evaluated by default like this
+a + (b * c)   // 7
+
+// now overriding precedence
+// addition before multiplication
+(a + b) * c   // 9
+
+// which is equivalent to
+a * c + b * c // 9
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-grouping-operator', 'The Grouping Operator')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-grouping-operator', 'The Grouping Operator')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-11.1.6', 'The Grouping Operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES1', '#sec-11.1.4', 'The Grouping Operator')}}{{Spec2('ES1')}}初始化定义.在JavaScript1.0中生效
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.grouping")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/in/index.html b/files/zh-cn/web/javascript/reference/operators/in/index.html new file mode 100644 index 0000000000..acd8d18255 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/in/index.html @@ -0,0 +1,145 @@ +--- +title: in +slug: Web/JavaScript/Reference/Operators/in +tags: + - JavaScript + - Operator + - Relational Operators +translation_of: Web/JavaScript/Reference/Operators/in +--- +

{{jsSidebar("Operators")}}

+ +

如果指定的属性在指定的对象或其原型链中,则in 运算符返回true

+ +
{{EmbedInteractiveExample("pages/js/expressions-inoperator.html")}}
+ + + +

语法

+ +
prop in object
+ +

参数

+ +
+
prop
+
一个字符串类型或者 symbol 类型的属性名或者数组索引(非symbol类型将会强制转为字符串)。
+
+ +
+
objectName
+
检查它(或其原型链)是否包含具有指定名称的属性的对象。
+
+ +

描述

+ +

下面的例子演示了一些 in 运算符的用法。

+ +
// 数组
+var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
+0 in trees        // 返回true
+3 in trees        // 返回true
+6 in trees        // 返回false
+"bay" in trees    // 返回false (必须使用索引号,而不是数组元素的值)
+
+"length" in trees // 返回true (length是一个数组属性)
+
+Symbol.iterator in trees // 返回true (数组可迭代,只在ES2015+上有效)
+
+
+// 内置对象
+"PI" in Math          // 返回true
+
+// 自定义对象
+var mycar = {make: "Honda", model: "Accord", year: 1998};
+"make" in mycar  // 返回true
+"model" in mycar // 返回true
+
+ +

in右操作数必须是一个对象值。例如,你可以指定使用String构造函数创建的字符串,但不能指定字符串文字。

+ +
var color1 = new String("green");
+"length" in color1 // 返回true
+var color2 = "coral";
+"length" in color2 // 报错(color2不是对象)
+
+ +

对被删除或值为 undefined 的属性使用in

+ +

如果你使用 delete 运算符删除了一个属性,则 in 运算符对所删除属性返回 false

+ +
var mycar = {make: "Honda", model: "Accord", year: 1998};
+delete mycar.make;
+"make" in mycar;  // 返回false
+
+var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
+delete trees[3];
+3 in trees; // 返回false
+
+ +

如果你只是将一个属性的值赋值为{{jsxref("Global_Objects/undefined", "undefined")}},而没有删除它,则 in 运算仍然会返回true

+ +
var mycar = {make: "Honda", model: "Accord", year: 1998};
+mycar.make = undefined;
+"make" in mycar;  // 返回true
+
+ +
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
+trees[3] = undefined;
+3 in trees; // 返回true
+
+ +

继承属性

+ +

如果一个属性是从原型链上继承来的,in 运算符也会返回 true

+ +
"toString" in {}; // 返回true
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational Operators')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-relational-operators', 'Relational Operators')}}{{Spec2('ES2015')}}
{{SpecName('ES5.1', '#sec-11.8.7', 'The in Operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.8.7', 'The in Operator')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.4.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.in")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/increment/index.html b/files/zh-cn/web/javascript/reference/operators/increment/index.html new file mode 100644 index 0000000000..afe307f389 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/increment/index.html @@ -0,0 +1,84 @@ +--- +title: 自增 (++) +slug: Web/JavaScript/Reference/Operators/Increment +tags: + - JavaScript + - Operator + - Reference +translation_of: Web/JavaScript/Reference/Operators/Increment +--- +
{{jsSidebar("Operators")}}
+ +

自增运算符 (++) 将其操作数递增(加1)并返回一个值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-increment.html")}}
+ + + +

语法

+ +
Operator: x++ or ++x
+
+ +

描述

+ +

如使用后置(Postfix)自增,操作符在操作数后(例如  x++), 操作数将在自增前返回。

+ +

如使用前置(Prefix)自增,操作符在操作数前(例如 ++x), 操作数将先自增后返回。

+ +

示例

+ +

后置自增(Postfix increment)

+ +
let x = 3;
+y = x++;
+
+// y = 3
+// x = 4
+
+ +

前置自增(Prefix increment)

+ +
let a = 2;
+b = ++a;
+
+// a = 3
+// b = 3
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-postfix-increment-operator', 'Increment operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.increment")}}

+ +

相关链接

+ + + +
+
+
diff --git a/files/zh-cn/web/javascript/reference/operators/index.html b/files/zh-cn/web/javascript/reference/operators/index.html new file mode 100644 index 0000000000..238cbb8cb9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/index.html @@ -0,0 +1,297 @@ +--- +title: 表达式和运算符 +slug: Web/JavaScript/Reference/Operators +tags: + - JavaScript + - Operators + - 概览 +translation_of: Web/JavaScript/Reference/Operators +--- +

{{jsSidebar("Operators")}}
+ 该章节说明了JavaScript语言所有的运算符,表达式和关键字。

+ +

表达式和运算符分类

+ +

左侧工具栏是按字母表排序的列表。

+ +

主要表达式

+ +

JavaScript中基本关键字和常用表达式。

+ +
+
{{jsxref("Operators/this", "this")}}
+
this 关键字指向函数的执行上下文。
+
{{jsxref("Operators/function", "function")}}
+
function 关键字定义了函数表达式。
+
{{jsxref("Operators/class", "class")}}
+
class 关键字定义了类表达式。
+
{{jsxref("Operators/function*", "function*")}}
+
function* 关键字定义了一个 generator 函数表达式。
+
{{jsxref("Operators/yield", "yield")}}
+
暂停和恢复 generator 函数。
+
{{jsxref("Operators/yield*", "yield*")}}
+
委派给另外一个generator函数或可迭代的对象。
+
{{jsxref("Operators/async_function", "async function")}}
+
async function 定义一个异步函数表达式。
+
{{jsxref("Operators/await", "await")}}
+
暂停或恢复执行异步函数,并等待promise的resolve/reject回调。
+
{{jsxref("Global_Objects/Array", "[]")}}
+
数组初始化/字面量语法。
+
{{jsxref("Operators/Object_initializer", "{}")}}
+
对象初始化/字面量语法。
+
{{jsxref("Global_Objects/RegExp", "/ab+c/i")}}
+
正则表达式字面量语法。
+
{{jsxref("Operators/Grouping", "( )")}}
+
分组操作符。
+
+ +

左表达式

+ +

左边的值是赋值的目标。

+ +
+
{{jsxref("Operators/Property_accessors", "属性访问符", "", 1)}}
+
成员运算符提供了对对象的属性或方法的访问
+ (object.property 和 object["property"]).
+
{{jsxref("Operators/new", "new")}}
+
new 运算符创建了构造函数实例。
+
{{JSxRef("Operators/new%2Etarget", "new.target")}}
+
在构造器中,new.target 指向{{jsxref("Operators/new", "new")}}调用的构造器。
+
{{jsxref("Operators/super", "super")}}
+
super 关键字调用父类的构造器.
+
{{jsxref("Operators/Spread_operator", "...obj")}}
+
展开运算符可以将一个可迭代的对象在函数调用的位置展开成为多个参数,或者在数组字面量中展开成多个数组元素。
+
+ +

自增和自减

+ +

前置/后置自增运算符和前置/后置自减运算符.

+ +
+
{{jsxref("Operators/Arithmetic_Operators", "A++", "#Increment")}}
+
后置自增运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "A--", "#Decrement")}}
+
后置自减运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "++A", "#Increment")}}
+
前置自增运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "--A", "#Decrement")}}
+
前置自减运算符.
+
+ +

一元运算符

+ +

一元运算符只有一个操作数.

+ +
+
{{jsxref("Operators/delete", "delete")}}
+
delete 运算符用来删除对象的属性.
+
{{jsxref("Operators/void", "void")}}
+
void 运算符表示表达式放弃返回值.
+
{{jsxref("Operators/typeof", "typeof")}}
+
typeof 运算符用来判断给定对象的类型.
+
{{jsxref("Operators/Arithmetic_Operators", "+", "#Unary_plus")}}
+
一元加运算符将操作转换为Number类型.
+
{{jsxref("Operators/Arithmetic_Operators", "-", "#Unary_negation")}}
+
一元减运算符将操作转换为Number类型并取反.
+
{{jsxref("Operators/Bitwise_Operators", "~", "#Bitwise_NOT")}}
+
按位非运算符.
+
{{jsxref("Operators/Logical_Operators", "!", "#Logical_NOT")}}
+
逻辑非运算符.
+
+ +

算术运算符

+ +

算术运算符以二个数值(字面量或变量)作为操作数,并返回单个数值。

+ +
+
{{jsxref("Operators/Arithmetic_Operators", "+", "#Addition")}}
+
加法运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "-", "#Subtraction")}}
+
减法运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "/", "#Division")}}
+
除法运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "*", "#Multiplication")}}
+
乘法运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "%", "#Remainder")}}
+
取模运算符.
+
+ +

关系运算符

+ +

比较运算符比较二个操作数并返回基于比较结果的Boolean值。

+ +
+
{{jsxref("Operators/in", "in")}}
+
in运算符用来判断对象是否拥有给定属性.
+
{{jsxref("Operators/instanceof", "instanceof")}}
+
instanceof 运算符判断一个对象是否是另一个对象的实例.
+
{{jsxref("Operators/Comparison_Operators", "<", "#Less_than_operator")}}
+
小于运算符
+
{{jsxref("Operators/Comparison_Operators", ">", "#Greater_than_operator")}}
+
大于运算符.
+
{{jsxref("Operators/Comparison_Operators", "<=", "#Less_than_or_equal_operator")}}
+
小于等于运算符.
+
{{jsxref("Operators/Comparison_Operators", ">=", "#Greater_than_or_equal_operator")}}
+
大于等于运算符。 
+
+ +
注意: => 不是运算符,而是{{jsxref("Functions/Arrow_functions", "箭头函数")}}的表示符。
+ +

相等运算符

+ +

如果相等,操作符返回的是Boolean(布尔)类型的true,否则是false。

+ +
+
{{jsxref("Operators/Comparison_Operators", "==", "#Equality")}}
+
相等 运算符.
+
{{jsxref("Operators/Comparison_Operators", "!=", "#Inequality")}}
+
不等 运算符.
+
{{jsxref("Operators/Comparison_Operators", "===", "#Identity")}}
+
全等 运算符.
+
{{jsxref("Operators/Comparison_Operators", "!==", "#Nonidentity")}}
+
非全等 运算符.
+
+ +

位移运算符

+ +

在二进制的基础上对数字进行移动操作

+ +
+
{{jsxref("Operators/Bitwise_Operators", "<<", "#Left_shift")}}
+
按位左移运算符。
+
{{jsxref("Operators/Bitwise_Operators", ">>", "#Right_shift")}}
+
按位右移运算符。
+
{{jsxref("Operators/Bitwise_Operators", ">>>", "#Unsigned_right_shift")}}
+
按位无符号右移运算符。
+
+ +

二进制位运算符

+ +

二进制运算符将它们的操作数作为32个二进制位(0或1)的集合,并返回标准的JavaScript数值。

+ +
+
{{jsxref("Operators/Bitwise_Operators", "&", "#Bitwise_AND")}}
+
二进制位与(AND)。
+
{{jsxref("Operators/Bitwise_Operators", "|", "#Bitwise_OR")}}
+
二进制位或(OR)。
+
{{jsxref("Operators/Bitwise_Operators", "^", "#Bitwise_XOR")}}
+
二进制位异或(XOR)。
+
+ +

二元逻辑运算符

+ +

逻辑运算符典型的用法是用于boolean(逻辑)值运算, 它们返回boolean值。

+ +
+
{{jsxref("Operators/Logical_Operators", "&&", "#Logical_AND")}}
+
逻辑与.
+
{{jsxref("Operators/Logical_Operators", "||", "#Logical_OR")}}
+
逻辑或.
+
{{JSxRef("Operators/Nullish_coalescing_operator", "??")}}
+
空值合并运算符 , 如果 ?? 前面是 null 或 undefined ,取后面的默认值
+
+ +

条件(三元)运算符

+ +
+
{{jsxref("Operators/Conditional_Operator", "(condition ? ifTrue : ifFalse)")}}
+
+

条件元素运算符把两个结果中其中一个符合运算逻辑的值返回。

+
+
+ +

赋值运算符

+ +

赋值元素符会将右边的操作数的值分配给左边的操作数,并将其值修改为右边操作数相等的值。

+ +
+
{{jsxref("Operators/Assignment_Operators", "=", "#Assignment")}}
+
赋值运算符。
+
{{jsxref("Operators/Assignment_Operators", "*=", "#Multiplication_assignment")}}
+
赋值乘积。
+
{{jsxref("Operators/Assignment_Operators", "/=", "#Division_assignment")}}
+
赋值商。
+
{{jsxref("Operators/Assignment_Operators", "%=", "#Remainder_assignment")}}
+
赋值求余。
+
{{jsxref("Operators/Assignment_Operators", "+=", "#Addition_assignment")}}
+
赋值求和。
+
{{jsxref("Operators/Assignment_Operators", "-=", "#Subtraction_assignment")}}
+
赋值求差。
+
{{jsxref("Operators/Assignment_Operators", "<<=", "#Left_shift_assignment")}}
+
左位移。
+
{{jsxref("Operators/Assignment_Operators", ">>=", "#Right_shift_assignment")}}
+
右位移。
+
{{jsxref("Operators/Assignment_Operators", ">>>=", "#Unsigned_right_shift_assignment")}}
+
无符号右位移。
+
{{jsxref("Operators/Assignment_Operators", "&=", "#Bitwise_AND_assignment")}}
+
赋值与。
+
{{jsxref("Operators/Assignment_Operators", "^=", "#Bitwise_XOR_assignment")}}
+
赋值按位异或。
+
{{jsxref("Operators/Assignment_Operators", "|=", "#Bitwise_OR_assignment")}}
+
赋值或。
+
{{jsxref("Operators/Destructuring_assignment", "[a, b] = [1, 2]")}}
+ {{jsxref("Operators/Destructuring_assignment", "{a, b} = {a:1, b:2}")}}
+
+

解构赋值允许你分配数组或者对象变量的属性通过使用规定的语法,其看起来和数组和对象字面量很相似。

+
+
+

逗号操作符

+
+
{{jsxref("Operators/Comma_Operator", ",")}}
+
逗号操作符允许在一个判断状态中有多个表达式去进行运算并且最后返回最后一个表达式的值。
+
+

非标准化特性

+
+
{{JSxRef("Operators/Expression_closures", "Expression closures", "", 1)}} {{non-standard_inline}}{{obsolete_inline(60)}}
+
闭包表达式语法是一个缩写简单的函数。
+
{{JSxRef("Operators/Legacy_generator_function", "Legacy generator function", "", 1)}} {{non-standard_inline}}{{obsolete_inline(58)}}
+
function关键字能用来定义表达式内部未执行完的function的余下功能。 为了能执行function内部余下的代码, 这个function的内部至少包含一个{{jsxref("Operators/yield", "yield")}} 表达式。
+
{{JSxRef("Operators/Array_comprehensions", "[for (x of y) x]")}} {{non-standard_inline}}{{obsolete_inline(58)}}
+
数组解析
+
{{JSxRef("Operators/Generator_comprehensions", "(for (x of y) y)")}} {{non-standard_inline}}{{obsolete_inline(58)}}
+
生成器解析
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1', '#sec-11', 'Expressions')}}{{Spec2('ES1')}}Initial definition
{{SpecName('ES5.1', '#sec-11', 'Expressions')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}{{Spec2('ES6')}}New: Spread syntax, rest syntax, destructuring assignment, super keyword.
{{SpecName('ESDraft', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/inequality/index.html b/files/zh-cn/web/javascript/reference/operators/inequality/index.html new file mode 100644 index 0000000000..2c0bccddfd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/inequality/index.html @@ -0,0 +1,104 @@ +--- +title: 不等于 (!=) +slug: Web/JavaScript/Reference/Operators/Inequality +tags: + - JavaScript + - 参考 + - 语言特征 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Inequality +--- +
{{jsSidebar("Operators")}}
+ +

不等于运算符 (!=) 检查其两个操作数是否不相等,并返回布尔结果。 与严格的不等式运算符不同,它尝试转换和比较不同类型的操作数。

+ +
{{EmbedInteractiveExample("pages/js/expressions-inequality.html")}}
+ + + +

语法

+ +
x != y
+ +

描述

+ +

不等式运算符检查其操作数是否不相等。这是等于运算符的取反,因此以下两行将始终给出相同的结果: 

+ +
x != y
+
+!(x == y)
+ +

有关比较算法的详细信息,请参见等于运算符的页面

+ +

与等于运算符一样,不等于运算符将尝试转换和比较不同类型的操作数:

+ +
3 != "3"; // false
+ +

为避免这种情况,并要求将不同类型视为不同,请使用严格的不等于运算符:

+ +
3 !== "3"; // true
+ +

例子

+ +

没有类型转换的比较

+ +
1 != 2;              // true
+"hello" != "hola";   // true
+
+1 != 1;              // false
+"hello" != "hello";  // false
+ +

与类型转换比较

+ +
"1" !=  1;            // false
+1 != "1";             // false
+0 != false;           // false
+0 != null;            // true
+0 != undefined;       // true
+0 != !!null;          // false, look at Logical NOT operator
+0 != !!undefined;     // false, look at Logical NOT operator
+null != undefined;    // false
+
+const number1 = new Number(3);
+const number2 = new Number(3);
+number1 != 3;         // false
+number1 != number2;   // true
+ +

对象比较

+ +
const object1 = {"key": "value"}
+const object2 = {"key": "value"};
+
+object1 != object2 // true
+object2 != object2 // false
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.inequality")}}

+ +

参见

+ + + +
+
+
diff --git a/files/zh-cn/web/javascript/reference/operators/instanceof/index.html b/files/zh-cn/web/javascript/reference/operators/instanceof/index.html new file mode 100644 index 0000000000..c97b2a72a4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/instanceof/index.html @@ -0,0 +1,186 @@ +--- +title: instanceof +slug: Web/JavaScript/Reference/Operators/instanceof +tags: + - JavaScript + - instanceof + - 原型 + - 原型链 + - 对象 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/instanceof +--- +
{{jsSidebar("Operators")}}
+ +

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

+ +
{{EmbedInteractiveExample("pages/js/expressions-instanceof.html")}}
+ + + +

语法

+ +
object instanceof constructor
+ +

参数

+ +
+
object
+
某个实例对象
+
+ +
+
constructor
+
某个构造函数
+
+ +

描述

+ +

instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。

+ +
// 定义构造函数
+function C(){}
+function D(){}
+
+var o = new C();
+
+
+o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
+
+
+o instanceof D; // false,因为 D.prototype 不在 o 的原型链上
+
+o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true
+C.prototype instanceof Object // true,同上
+
+C.prototype = {};
+var o2 = new C();
+
+o2 instanceof C; // true
+
+o instanceof C; // false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上.
+
+D.prototype = new C(); // 继承
+var o3 = new D();
+o3 instanceof D; // true
+o3 instanceof C; // true 因为 C.prototype 现在在 o3 的原型链上
+
+ +

需要注意的是,如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 Foo.prototype 属性的值有可能会改变,改变之后的值很有可能不存在于 obj 的原型链上,这时原表达式的值就会成为 false。另外一种情况下,原表达式的值也会改变,就是改变对象 obj 的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 __proto__ 伪属性,是可以实现的。比如执行 obj.__proto__ = {} 之后,obj instanceof Foo 就会返回 false 了。

+ +

instanceof 和多全局对象(例如:多个 frame 或多个 window 之间的交互)

+ +

在浏览器中,我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 [] instanceof window.frames[0].Array 会返回 false,因为 Array.prototype !== window.frames[0].Array.prototype,并且数组从前者继承。

+ +

起初,你会认为这样并没有意义,但是当你在你的脚本中开始处理多个 frame 或多个 window 以及通过函数将对象从一个窗口传到另一个窗口时,这就是一个有效而强大的话题。比如,实际上你可以通过使用Array.isArray(myObj) 或者Object.prototype.toString.call(myObj) === "[object Array]" 来安全的检测传过来的对象是否是一个数组。

+ +

比如检测一个 Nodes 在另一个窗口中是不是 SVGElement,你可以使用myNode instanceof myNode.ownerDocument.defaultView.SVGElement

+ +
Mozilla开发者注意:
+在代码中使用 XPCOM instanceof 有特殊影响: 如果查询接口成功执行后,obj instanceof xpcomInterface (e.g. Components.interfaces.nsIFile) 调用obj.QueryInterface(xpcomInterface) 并且返回 true 。这种调用的副作用是在一次成功的 instanceof 测试后,你可以在 obj 上使用xpcomInterface 的属性。这与标准的 JavaScript 全局变量不同,即使 obj 来自不同的作用域,obj instanceof xpcomInterface 也可以按预期产生作用。
+ +

示例

+ +

演示 String 对象和 Date 对象都属于 Object 类型和一些特殊情况

+ +

下面的代码使用了 instanceof 来证明:String 和 Date 对象同时也属于Object 类型(他们是由 Object 类派生出来的)。

+ +

但是,使用对象文字符号创建的对象在这里是一个例外:虽然原型未定义,但 instanceof Object 返回 true

+ +
var simpleStr = "This is a simple string";
+var myString  = new String();
+var newStr    = new String("String created with constructor");
+var myDate    = new Date();
+var myObj     = {};
+var myNonObj  = Object.create(null);
+
+simpleStr instanceof String; // 返回 false, 检查原型链会找到 undefined
+myString  instanceof String; // 返回 true
+newStr    instanceof String; // 返回 true
+myString  instanceof Object; // 返回 true
+
+myObj instanceof Object;    // 返回 true, 尽管原型没有定义
+({})  instanceof Object;    // 返回 true, 同上
+myNonObj instanceof Object; // 返回 false, 一种创建非 Object 实例的对象的方法
+
+myString instanceof Date; //返回 false
+
+myDate instanceof Date;     // 返回 true
+myDate instanceof Object;   // 返回 true
+myDate instanceof String;   // 返回 false
+ +

演示 mycar 属于 Car 类型的同时又属于 Object 类型

+ +

下面的代码创建了一个类型 Car,以及该类型的对象实例 mycar. instanceof 运算符表明了这个 mycar 对象既属于 Car 类型,又属于 Object 类型。

+ +
function Car(make, model, year) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+}
+var mycar = new Car("Honda", "Accord", 1998);
+var a = mycar instanceof Car;    // 返回 true
+var b = mycar instanceof Object; // 返回 true
+
+
+ +

不是...的实例

+ +

要检测对象不是某个构造函数的实例时,你可以这样做

+ +
if (!(mycar instanceof Car)) {
+  // Do something, like mycar = new Car(mycar)
+}
+ +

这和以下代码完全不同

+ +
if (!mycar instanceof Car)
+ +

这段代码永远会得到 false!mycar 将在 instanceof 之前被处理,所以你总是在验证一个布尔值是否是 Car 的一个实例)。

+ +

相关规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational Operators')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-relational-operators', 'Relational Operators')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.8.6', 'The instanceof operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.8.6', 'The instanceof operator')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.4.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.instanceof")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/left_shift/index.html b/files/zh-cn/web/javascript/reference/operators/left_shift/index.html new file mode 100644 index 0000000000..aba9c6bee2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/left_shift/index.html @@ -0,0 +1,72 @@ +--- +title: 左移 (<<) +slug: Web/JavaScript/Reference/Operators/Left_shift +translation_of: Web/JavaScript/Reference/Operators/Left_shift +--- +
{{jsSidebar("Operators")}}
+ +

左移操作符 (<<) 将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。

+ +
{{EmbedInteractiveExample("pages/js/expressions-left-shift.html")}}
+ + + +

语法

+ +
a << b
+
+ +

描述

+ +

左移操作符将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。

+ +

例如, 9 << 2 得出 36:

+ +
.    9 (十进制): 00000000000000000000000000001001 (二进制)
+                  --------------------------------
+9 << 2 (十进制): 00000000000000000000000000100100 (二进制) = 36 (十进制)
+
+ +

移动任意数字 x 至左边 y 位,得出 x * 2 ** y 。
+ 所以例如:9 << 3 等价于 9 * 2³ = 9 * 8 = 72

+ +

例子

+ +

使用左移

+ +
9 << 3; // 72
+
+// 9 * 2³ = 9 * 8 = 72
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.left_shift")}}

+ +

参见

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/left_shift_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/left_shift_assignment/index.html new file mode 100644 index 0000000000..3ebe7cef88 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/left_shift_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: Left shift assignment (<<=) +slug: Web/JavaScript/Reference/Operators/Left_shift_assignment +translation_of: Web/JavaScript/Reference/Operators/Left_shift_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The left shift assignment operator (<<=) moves the specified amount of bits to the left and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-left-shift-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x <<= y
+Meaning:  x   = x << y
+ +

Examples

+ +

Using left shift assignment

+ +
let a = 5;
+// 00000000000000000000000000000101
+
+a <<= 2; // 20
+// 00000000000000000000000000010100
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.left_shift_assignment")}}

+ +

See also

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/less_than/index.html b/files/zh-cn/web/javascript/reference/operators/less_than/index.html new file mode 100644 index 0000000000..1a33554b98 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/less_than/index.html @@ -0,0 +1,110 @@ +--- +title: Less than (<) +slug: Web/JavaScript/Reference/Operators/Less_than +translation_of: Web/JavaScript/Reference/Operators/Less_than +--- +
{{jsSidebar("Operators")}}
+ +

The less than operator (<) returns true if the left operand is less than the right operand, and false otherwise.

+ +
{{EmbedInteractiveExample("pages/js/expressions-less-than.html")}}
+ + + +

语法

+ +
 x < y
+ +

Description

+ +

The operands are compared using the Abstract Relational Comparison algorithm, which is roughly summarised below:

+ + + +

Examples

+ +

String to string comparison

+ +
console.log("a" < "b");        // true
+console.log("a" < "a");        // false
+console.log("a" < "3");        // false
+ +

String to number comparison

+ +
console.log("5" < 3);          // false
+console.log("3" < 3);          // false
+console.log("3" < 5);          // true
+
+console.log("hello" < 5);      // false
+console.log(5 < "hello");      // false
+
+console.log("5" < 3n);         // false
+console.log("3" < 5n);         // true
+ +

Number to Number comparison

+ +
console.log(5 < 3);            // false
+console.log(3 < 3);            // false
+console.log(3 < 5);            // true
+ +

Number to BigInt comparison

+ +
console.log(5n < 3);           // false
+console.log(3 < 5n);           // true
+ +

Comparing Boolean, null, undefined, NaN

+ +
console.log(true < false);     // false
+console.log(false < true);     // true
+
+console.log(0 < true);         // true
+console.log(true < 1);         // false
+
+console.log(null < 0);         // false
+console.log(null < 1);         // true
+
+console.log(undefined < 3);    // false
+console.log(3 < undefined);    // false
+
+console.log(3 < NaN);          // false
+console.log(NaN < 3);          // false
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.less_than")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/less_than_or_equal/index.html b/files/zh-cn/web/javascript/reference/operators/less_than_or_equal/index.html new file mode 100644 index 0000000000..97a6f6746b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/less_than_or_equal/index.html @@ -0,0 +1,97 @@ +--- +title: 小于或等于 +slug: Web/JavaScript/Reference/Operators/Less_than_or_equal +translation_of: Web/JavaScript/Reference/Operators/Less_than_or_equal +--- +
{{jsSidebar("Operators")}}
+ +

The less than or equal operator (<=) returns true if the left operand is less than or equal to the right operand, and false otherwise.

+ +
{{EmbedInteractiveExample("pages/js/expressions-less-than-or-equal.html")}}
+ + + +

Syntax

+ +
 x <= y
+ +

Description

+ +

The operands are compared using the Abstract Relational Comparison algorithm. See the documentation for the Less than operator for a summary of this algorithm.

+ +

Examples

+ +

String to string comparison

+ +
console.log("a" <= "b");     // true
+console.log("a" <= "a");     // true
+console.log("a" <= "3");     // false
+
+ +

String to number comparison

+ +
console.log("5" <= 3);       // false
+console.log("3" <= 3);       // true
+console.log("3" <= 5);       // true
+
+console.log("hello" <= 5);   // false
+console.log(5 <= "hello");   // false
+ +

Number to Number comparison

+ +
console.log(5 <= 3);         // false
+console.log(3 <= 3);         // true
+console.log(3 <= 5);         // true
+ +

Number to BigInt comparison

+ +
console.log(5n <= 3);        // false
+console.log(3 <= 3n);        // true
+console.log(3 <= 5n);        // true
+ +

Comparing Boolean, null, undefined, NaN

+ +
console.log(true <= false);  // false
+console.log(true <= true);   // true
+console.log(false <= true);  // true
+
+console.log(true <= 0);      // false
+console.log(true <= 1);      // true
+
+console.log(null <= 0);      // true
+console.log(1 <= null);      // false
+
+console.log(undefined <= 3); // false
+console.log(3 <= undefined); // false
+
+console.log(3 <= NaN);       // false
+console.log(NaN <= 3);       // false
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.less_than_or_equal")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/logical_and_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/logical_and_assignment/index.html new file mode 100644 index 0000000000..3ed9a1582a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_and_assignment/index.html @@ -0,0 +1,83 @@ +--- +title: Logical AND assignment (&&=) +slug: Web/JavaScript/Reference/Operators/Logical_AND_assignment +translation_of: Web/JavaScript/Reference/Operators/Logical_AND_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The logical AND assignment (x &&= y) operator only assigns if x is {{Glossary("truthy")}}.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-and-assignment.html")}}
+ + + +

语法

+ +
expr1 &&= expr2
+
+ +

描述

+ +

Short-circuit evaluation

+ +

The logical AND operator is evaluated left to right, it is tested for possible short-circuit evaluation using the following rule:

+ +

(some falsy expression) && expr is short-circuit evaluated to the falsy expression;

+ +

Short circuit means that the expr part above is not evaluated, hence any side effects of doing so do not take effect (e.g., if expr is a function call, the calling never takes place).

+ +

Logical AND assignment short-circuits as well meaning that x &&= y is equivalent to:

+ +
x && (x = y);
+ +

And not equivalent to the following which would always perform an assignment:

+ +
x = x && y;
+
+ +

例子

+ +

Using logical AND assignment

+ +
let x = 0;
+let y = 1;
+
+x &&= 0; // 0
+x &&= 1; // 0
+y &&= 1; // 1
+y &&= 0; // 0
+
+ +

规范

+ + + + + + + + + + + + + + +
Specification
{{SpecName('Logical Assignment', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.logical_and_assignment")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/logical_not/index.html b/files/zh-cn/web/javascript/reference/operators/logical_not/index.html new file mode 100644 index 0000000000..75084956a7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_not/index.html @@ -0,0 +1,104 @@ +--- +title: Logical NOT (!) +slug: Web/JavaScript/Reference/Operators/Logical_NOT +translation_of: Web/JavaScript/Reference/Operators/Logical_NOT +--- +
{{jsSidebar("Operators")}}
+ +

The logical NOT (!) operator (logical complement, negation) takes truth to falsity and vice versa. It is typically used with {{jsxref("Boolean")}} (logical) values. When used with non-Boolean values, it returns false if its single operand can be converted to true; otherwise, returns true.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-not.html", "shorter")}}
+ + + +

语法

+ +
!expr
+
+ +

Description

+ +

Returns false if its single operand can be converted to true; otherwise, returns true.

+ +

If a value can be converted to true, the value is so-called {{Glossary("truthy")}}. If a value can be converted to false, the value is so-called {{Glossary("falsy")}}.

+ +

Examples of expressions that can be converted to false are:

+ + + +

Even though the ! operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.

+ +

Examples

+ +

Using NOT

+ +

The following code shows examples of the ! (logical NOT) operator.

+ +
n1 = !true               // !t returns false
+n2 = !false              // !f returns true
+n3 = !''                 // !f returns true
+n4 = !'Cat'              // !t returns false
+ +

Double NOT (!!)

+ +

It is possible to use a couple of NOT operators in series to explicitly force the conversion of any value to the corresponding boolean primitive. The conversion is based on the "truthyness" or "falsyness" of the value (see {{Glossary("truthy")}} and {{Glossary("falsy")}}).

+ +

The same conversion can be done through the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} function.

+ +
n1 = !!true                   // !!truthy returns true
+n2 = !!{}                     // !!truthy returns true: any object is truthy...
+n3 = !!(new Boolean(false))   // ...even Boolean objects with a false .valueOf()!
+n4 = !!false                  // !!falsy returns false
+n5 = !!""                     // !!falsy returns false
+n6 = !!Boolean(false)         // !!falsy returns false
+ +

Converting between NOTs

+ +

The following operation involving booleans:

+ +
!!bCondition
+ +

is always equal to:

+ +
bCondition
+ +

Specifications

+ + + + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-logical-not-operator', 'Logical NOT expression')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.logical_not")}}

+ +

See also

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/logical_nullish_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/logical_nullish_assignment/index.html new file mode 100644 index 0000000000..a57c18e5c2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_nullish_assignment/index.html @@ -0,0 +1,82 @@ +--- +title: 逻辑空赋值 (??=) +slug: Web/JavaScript/Reference/Operators/Logical_nullish_assignment +translation_of: Web/JavaScript/Reference/Operators/Logical_nullish_assignment +--- +
{{jsSidebar("Operators")}}
+ +

逻辑空赋值运算符 (x ??= y) 仅在 x 是 {{Glossary("nullish")}} (null 或 undefined) 时对其赋值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-nullish-assignment.html")}}
+ + + +

语法

+ +
expr1 ??= expr2
+
+ +

描述

+ +

语法短路求值

+ +

空值合并运算符从左至右求值,其使用以下规则测试是否可能进行语法短路求值:

+ +

(结果非 null 或 undefined 的表达式) ?? expr 被短路求值为左侧表达式,当左侧证明为既非 null 也非 undefined.

+ +

语法短路意味着 expr 部分尚未被求值,因此任何与其求值产生的相关副作用都不会生效(例如,如果 expr 是一个函数调用,则该调用将不会发生)。

+ +

逻辑空赋值的语法短路也意味着 x ??= y 等价于:

+ +
x ?? (x = y);
+ +

而不等价于如下的表达式,因为其一定会发生赋值:

+ +
x = x ?? y;
+
+ +

例子

+ +

使用逻辑空赋值

+ +
function config(options) {
+  options.duration ??= 100;
+  options.speed ??= 25;
+  return options;
+}
+
+config({ duration: 125 }); // { duration: 125, speed: 25 }
+config({}); // { duration: 100, speed: 25 }
+
+ +

规范

+ + + + + + + + + + + + + + +
规范
{{SpecName('Logical Assignment', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.logical_nullish_assignment")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/logical_operators/index.html b/files/zh-cn/web/javascript/reference/operators/logical_operators/index.html new file mode 100644 index 0000000000..ba2b8c21bb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_operators/index.html @@ -0,0 +1,237 @@ +--- +title: 逻辑运算符 +slug: Web/JavaScript/Reference/Operators/Logical_Operators +tags: + - JavaScript + - 操作符 + - 逻辑 +translation_of: Web/JavaScript/Reference/Operators +--- +
{{jsSidebar("Operators")}}
+ +

逻辑运算符通常用于{{jsxref("Boolean","布尔")}}型(逻辑)值。这种情况下,它们返回一个布尔值。然而,&&|| 运算符会返回一个指定操作数的值,因此,这些运算符也用于非布尔值。这时,它们也就会返回一个非布尔型值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-logicaloperator.html")}}
+ + + +

描述

+ +

逻辑运算符如下表所示 (其中expr可能是任何一种类型, 不一定是布尔值):

+ + + + + + + + + + + + + + + + + + + + + + + + +
运算符语法说明
逻辑与,AND(&&expr1 && expr2expr1 可转换为 true,则返回 expr2;否则,返回 expr1
逻辑或,OR(||expr1 || expr2expr1 可转换为 true,则返回 expr1;否则,返回 expr2
逻辑非,NOT(!!exprexpr 可转换为 true,则返回 false;否则,返回 true
+ +

如果一个值可以被转换为 true,那么这个值就是所谓的 {{Glossary("truthy")}},如果可以被转换为 false,那么这个值就是所谓的 {{Glossary("falsy")}}。

+ +

会被转换为 false 的表达式有:

+ + + +

尽管 &&|| 运算符能够使用非布尔值的操作数, 但它们依然可以被看作是布尔操作符,因为它们的返回值总是能够被转换为布尔值。如果要显式地将它们的返回值(或者表达式)转换为布尔值,请使用双重非运算符(即!!)或者Boolean构造函数。

+ +

短路计算

+ +

由于逻辑表达式的运算顺序是从左到右,也可以用以下规则进行"短路"计算:

+ + + +

短路意味着上述表达式中的expr部分不会被执行,因此expr的任何副作用都不会生效(举个例子,如果expr是一次函数调用,这次调用就不会发生)。造成这种现象的原因是,整个表达式的值在第一个操作数被计算后已经确定了。看一个例子:

+ +
function A(){ console.log('called A'); return false; }
+function B(){ console.log('called B'); return true; }
+
+console.log( A() && B() );
+// logs "called A" due to the function call,
+// then logs false (which is the resulting value of the operator)
+
+console.log( B() || A() );
+// logs "called B" due to the function call,
+// then logs true (which is the resulting value of the operator)
+
+ +

Operators precedence

+ +

请注意,由于运算符优先级的存在,下面的表达式的结果却不相同。右侧被小括号括起来的操作变成了独立的表达式。

+ +
false &&  true || true      // 结果为 true
+false && (true || true)     // 结果为 false
+
+ +

逻辑与(&&

+ +

下面的代码是 && (逻辑与) 运算符的示例.

+ +
a1 = true  && true      // t && t 返回 true
+a2 = true  && false     // t && f 返回 false
+a3 = false && true      // f && t 返回 false
+a4 = false && (3 == 4)  // f && f 返回 false
+a5 = "Cat" && "Dog"     // t && t 返回 "Dog"
+a6 = false && "Cat"     // f && t 返回 false
+a7 = "Cat" && false     // t && f 返回 false
+a8 = ''    && false     // f && f 返回 ""
+a9 = false && ''        // f && f 返回 false
+
+ +

逻辑或(||

+ +

下面的代码是 || (逻辑或) 运算符的示例。

+ +
o1 = true  || true      // t || t 返回 true
+o2 = false || true      // f || t 返回 true
+o3 = true  || false     // t || f 返回 true
+o4 = false || (3 == 4)  // f || f 返回 false
+o5 = "Cat" || "Dog"     // t || t 返回 "Cat"
+o6 = false || "Cat"     // f || t 返回 "Cat"
+o7 = "Cat" || false     // t || f 返回 "Cat"
+o8 = ''    || false     // f || f 返回 false
+o9 = false || ''        // f || f 返回 ""
+
+ +

逻辑非(!

+ +

下面的代码是 ! (逻辑非) 运算符的示例.

+ +
n1 = !true              // !t 返回 false
+n2 = !false             // !f 返回 true
+n3 = !''                // !f 返回 true
+n4 = !'Cat'             // !t 返回 false
+
+ +

双重非(!!)运算符

+ +

可能使用双重非运算符的一个场景,是显式地将任意值强制转换为其对应的布尔值。这种转换是基于被转换值的 "truthyness" 和 "falsyness"的(参见 {{Glossary("truthy")}} 和 {{Glossary("falsy")}})。

+ +

同样的转换可以通过 Boolean 函数完成。

+ +
n1 = !!true                   // !!truthy 返回 true
+n2 = !!{}                     // !!truthy 返回 true: 任何 对象都是 truthy 的…
+n3 = !!(new Boolean(false))   // …甚至 .valueOf() 返回 false 的布尔值对象也是!
+n4 = !!false                  // !!falsy 返回 false
+n5 = !!""                     // !!falsy 返回 false
+n6 = !!Boolean(false)         // !!falsy 返回 false
+
+ +

布尔值转换规则

+ +

将 AND 转换为 OR

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 && bCondition2
+ +

总是等于:

+ +
!(!bCondition1 || !bCondition2)
+ +

将 OR 转换为 AND

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 || bCondition2
+ +

总是等于:

+ +
!(!bCondition1 && !bCondition2)
+ +

删除嵌套的小括号

+ +

由于逻辑表达式是从左往右计算的,所以,通常可以按照下面的规则删除小括号。

+ +

删除嵌套的 AND

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 || (bCondition2 && bCondition3)
+ +

总是等于:

+ +
bCondition1 || bCondition2 && bCondition3
+ +

删除嵌套的 OR

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 && (bCondition2 || bCondition3)
+ +

总是等于:

+ +
!(!bCondition1 || !bCondition2 && !bCondition3)
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.11')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
{{SpecName('ES6', '#sec-binary-logical-operators')}}{{Spec2('ES6')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
{{SpecName('ESDraft', '#sec-binary-logical-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.logical")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/logical_or/index.html b/files/zh-cn/web/javascript/reference/operators/logical_or/index.html new file mode 100644 index 0000000000..1a8f881377 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_or/index.html @@ -0,0 +1,146 @@ +--- +title: Logical OR (||) +slug: Web/JavaScript/Reference/Operators/Logical_OR +translation_of: Web/JavaScript/Reference/Operators/Logical_OR +--- +
{{jsSidebar("Operators")}}
+ +

The logical OR (||) operator (logical disjunction) for a set of operands is true if and only if one or more of its operands is true. It is typically used with {{jsxref("Boolean")}} (logical) values. When it is, it returns a Boolean value. However, the || operator actually returns the value of one of the specified operands, so if this operator is used with non-Boolean values, it will return a non-Boolean value.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-or.html", "shorter")}}
+ + + +

语法

+ +
expr1 || expr2
+
+ +

Description

+ +

If expr1 can be converted to true, returns expr1; else, returns expr2.

+ +

If a value can be converted to true, the value is so-called {{Glossary("truthy")}}. If a value can be converted to false, the value is so-called {{Glossary("falsy")}}.

+ +

Examples of expressions that can be converted to false are:

+ + + +

Even though the || operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.

+ +

Short-circuit evaluation

+ +

The logical OR expression is evaluated left to right, it is tested for possible "short-circuit" evaluation using the following rule:

+ +

(some truthy expression) || expr is short-circuit evaluated to the truthy expression.

+ +

Short circuit means that the expr part above is not evaluated, hence any side effects of doing so do not take effect (e.g., if expr is a function call, the calling never takes place). This happens because the value of the operator is already determined after the evaluation of the first operand. See example:

+ +
function A(){ console.log('called A'); return false; }
+function B(){ console.log('called B'); return true; }
+
+console.log( B() || A() );
+// logs "called B" due to the function call,
+// then logs true (which is the resulting value of the operator)
+
+ +

Operator precedence

+ +

The following expressions might seem equivalent, but they are not, because the && operator is executed before the || operator (see operator precedence).

+ +
true || false && false      // returns true, because && is executed first
+(true || false) && false    // returns false, because operator precedence cannot apply
+ +

Examples

+ +

Using OR

+ +

The following code shows examples of the || (logical OR) operator.

+ +
o1 = true  || true       // t || t returns true
+o2 = false || true       // f || t returns true
+o3 = true  || false      // t || f returns true
+o4 = false || (3 == 4)   // f || f returns false
+o5 = 'Cat' || 'Dog'      // t || t returns "Cat"
+o6 = false || 'Cat'      // f || t returns "Cat"
+o7 = 'Cat' || false      // t || f returns "Cat"
+o8 = ''    || false      // f || f returns false
+o9 = false || ''         // f || f returns ""
+o10 = false || varObject // f || object returns varObject
+
+ +
+

Note: If you use this operator to provide a default value to some variable, be aware that any falsy value will not be used. If you only need to filter out {{jsxref("null")}} or {{jsxref("undefined")}}, consider using the nullish coalescing operator.

+
+ +

Conversion rules for booleans

+ +

Converting AND to OR

+ +

The following operation involving booleans:

+ +
bCondition1 && bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 || !bCondition2)
+ +

Converting OR to AND

+ +

The following operation involving booleans:

+ +
bCondition1 || bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 && !bCondition2)
+ +

Removing nested parentheses

+ +

As logical expressions are evaluated left to right, it is always possible to remove parentheses from a complex expression following some rules.

+ +

The following composite operation involving booleans:

+ +
bCondition1 && (bCondition2 || bCondition3)
+ +

is always equal to:

+ +
!(!bCondition1 || !bCondition2 && !bCondition3)
+ +

Specifications

+ + + + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-LogicalORExpression', 'Logical OR expression')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.logical_or")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/logical_or_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/logical_or_assignment/index.html new file mode 100644 index 0000000000..ddd0dc8c79 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_or_assignment/index.html @@ -0,0 +1,87 @@ +--- +title: Logical OR assignment (||=) +slug: Web/JavaScript/Reference/Operators/Logical_OR_assignment +translation_of: Web/JavaScript/Reference/Operators/Logical_OR_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The logical OR assignment (x ||= y) operator only assigns if x is {{Glossary("falsy")}}.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-or-assignment.html")}}
+ + + +

 语法

+ +
expr1 ||= expr2
+
+ +

描述

+ +

Short-circuit evaluation

+ +

The logical OR operator works like this:

+ +
x || y;
+// returns x when x is truthy
+// returns y when x is not truthy
+ +

The logical OR operator short-circuits: the second operand is only evaluated if the first operand doesn’t already determine the result.

+ +

Logical OR assignment short-circuits as well, meaning it only performs an assignment if the logical operation would evaluate the right-hand side. In other words, x ||= y is equivalent to:

+ +
x || (x = y);
+
+ +

And not equivalent to the following which would always perform an assignment:

+ +
x = x || y;
+
+ +

Note that this behavior is different to mathematical and bitwise assignment operators.

+ +

例子

+ +

Setting default content

+ +

If the "lyrics" element is empty, set the innerHTML to a default value:

+ +
document.getElementById('lyrics').innerHTML ||= '<i>No lyrics.</i>'
+ +

Here the short-circuit is especially beneficial, since the element will not be updated unnecessarily and won't cause unwanted side-effects such as additional parsing or rendering work, or loss of focus, etc.

+ +

Note: Pay attention to the value returned by the API you're checking against. If an empty string is returned (a {{Glossary("falsy")}} value), ||= must be used, otherwise you want to use the ??= operator (for {{jsxref("null")}} or {{jsxref("undefined")}} return values).

+ +

规范

+ + + + + + + + + + + + + + +
Specification
{{SpecName('Logical Assignment', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.logical_or_assignment")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/multiplication/index.html b/files/zh-cn/web/javascript/reference/operators/multiplication/index.html new file mode 100644 index 0000000000..db346f4cbe --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/multiplication/index.html @@ -0,0 +1,69 @@ +--- +title: 乘法 (*) +slug: Web/JavaScript/Reference/Operators/Multiplication +translation_of: Web/JavaScript/Reference/Operators/Multiplication +--- +
{{jsSidebar("Operators")}}
+ +

乘法运算符 (*) 计算操作数的乘积。

+ +
{{EmbedInteractiveExample("pages/js/expressions-multiplication.html")}}
+ +
+ + + +

语法

+ +
Operator: x * y
+
+ +

例子

+ +

使用数字相乘

+ +
 2 * 2      // 4
+-2 * 2     // -4
+
+ +

使用 Infinity 相乘

+ +
Infinity * 0         // NaN
+Infinity * Infinity  // Infinity
+ +

使用非数字相乘

+ +
'foo' * 2 // NaN
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Multiplication operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.multiplication")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/multiplication_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/multiplication_assignment/index.html new file mode 100644 index 0000000000..e05019acba --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/multiplication_assignment/index.html @@ -0,0 +1,55 @@ +--- +title: Multiplication assignment (*=) +slug: Web/JavaScript/Reference/Operators/Multiplication_assignment +translation_of: Web/JavaScript/Reference/Operators/Multiplication_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The multiplication assignment operator (*=) multiplies a variable by the value of the right operand and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-multiplication-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x *= y
+Meaning:  x  = x * y
+ +

Examples

+ +

Using multiplication assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar *= 2     // 10
+bar *= 'foo' // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.multiplication_assignment")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/new.target/index.html b/files/zh-cn/web/javascript/reference/operators/new.target/index.html new file mode 100644 index 0000000000..7d1c41ec89 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/new.target/index.html @@ -0,0 +1,99 @@ +--- +title: new.target +slug: Web/JavaScript/Reference/Operators/new.target +tags: + - Classes + - ECMAScript 2015 + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Operators/new.target +--- +
{{JSSidebar("Operators")}}
+ +
new.target属性允许你检测函数或构造方法是否是通过new运算符被调用的。在通过new运算符被初始化的函数或构造方法中,new.target返回一个指向构造方法或函数的引用。在普通的函数调用中,new.target 的值是{{jsxref("undefined")}}。
+ +

语法

+ +
new.target
+ +

描述

+ +

new.target语法由一个关键字"new",一个点,和一个属性名"target"组成。通常"new."作用是提供属性访问的上下文,但这里"new."其实不是一个真正的对象。不过在构造方法调用中,new.target指向被new调用的构造函数,所以"new."成为了一个虚拟上下文。

+ +

new.target属性适用于所有函数访问的元属性。在  arrow functions 中,new.target 指向最近的外层函数的new.target(An arrow function expression does not have its own this, arguments, super , or new.target) 。

+ +

示例

+ +

函数调用中的 new.target

+ +

在普通的函数调用中(和作为构造函数来调用相对),new.target的值是{{jsxref("undefined")}}。这使得你可以检测一个函数是否是作为构造函数通过new被调用的。

+ +
function Foo() {
+  if (!new.target) throw "Foo() must be called with new";
+  console.log("Foo instantiated with new");
+}
+
+Foo(); // throws "Foo() must be called with new"
+new Foo(); // logs "Foo instantiated with new"
+
+ +

构造方法中的 new.target

+ +

在类的构造方法中,new.target指向直接被new执行的构造函数。并且当一个父类构造方法在子类构造方法中被调用时,情况与之相同。

+ +
class A {
+  constructor() {
+    console.log(new.target.name);
+  }
+}
+
+class B extends A { constructor() { super(); } }
+
+var a = new A(); // logs "A"
+var b = new B(); // logs "B"
+
+class C { constructor() { console.log(new.target); } }
+class D extends C { constructor() { super(); } }
+
+var c = new C(); // logs class C{constructor(){console.log(new.target);}}
+var d = new D(); // logs class D extends C{constructor(){super();}}
+
+ +

从上面类 C 和 D 的例子可以看出来,new.target 指向的是初始化类的类定义。比如当 D 通过 new 初始化的时候,打印出了 D 的类定义,C 的例子与之类似,打印出的是 C 的类定义。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-built-in-function-objects', 'Built-in Function Objects')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-built-in-function-objects', 'Built-in Function Objects')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.new_target")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/new/index.html b/files/zh-cn/web/javascript/reference/operators/new/index.html new file mode 100644 index 0000000000..16ae8bfd75 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/new/index.html @@ -0,0 +1,201 @@ +--- +title: new 运算符 +slug: Web/JavaScript/Reference/Operators/new +tags: + - JavaScript + - Left-hand-side expressions + - Operator + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/new +--- +
{{jsSidebar("Operators")}}
+ +

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

+ +
    +
+ +

{{EmbedInteractiveExample("pages/js/expressions-newoperator.html")}}

+ +

语法

+ +
new constructor[([arguments])]
+ +

参数

+ +
+
constructor
+
一个指定对象实例的类型的类或函数。
+
+ +
+
arguments
+
一个用于被 constructor 调用的参数列表。
+
+ +

描述

+ +

new 关键字会进行如下的操作:

+ +
    +
  1. 创建一个空的简单JavaScript对象(即{});
  2. +
  3. 链接该对象(设置该对象的constructor)到另一个对象 ;
  4. +
  5. 将步骤1新创建的对象作为this的上下文 ;
  6. +
  7. 如果该函数没有返回对象,则返回this
  8. +
+ +

(译注:关于对象的 constructor,参见 Object.prototype.constructor

+ +

创建一个用户自定义的对象需要两步:

+ +
    +
  1. 通过编写函数来定义对象类型。
  2. +
  3. 通过 new 来创建对象实例。
  4. +
+ +

创建一个对象类型,需要创建一个指定其名称和属性的函数;对象的属性可以指向其他对象,看下面的例子:

+ +

当代码 new Foo(...) 执行时,会发生以下事情:

+ +
    +
  1. 一个继承自 Foo.prototype 的新对象被创建。
  2. +
  3. 使用指定的参数调用构造函数 Foo,并将 this 绑定到新创建的对象。new Foo 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。
  4. +
  5. 由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)
  6. +
+ +

你始终可以对已定义的对象添加新的属性。例如,car1.color = "black" 语句给 car1 添加了一个新的属性 color,并给这个属性赋值 "black"。但是,这不会影响任何其他对象。要将新属性添加到相同类型的所有对象,你必须将该属性添加到 Car 对象类型的定义中。

+ +

你可以使用 Function.prototype 属性将共享属性添加到以前定义的对象类型。这定义了一个由该函数创建的所有对象共享的属性,而不仅仅是对象类型的其中一个实例。下面的代码将一个值为 nullcolor 属性添加到 car 类型的所有对象,然后仅在实例对象 car1 中用字符串 "black" 覆盖该值。详见 prototype

+ +
function Car() {}
+car1 = new Car();
+car2 = new Car();
+
+console.log(car1.color);    // undefined
+
+Car.prototype.color = "original color";
+console.log(car1.color);    // original color
+
+car1.color = 'black';
+console.log(car1.color);   // black
+
+console.log(car1.__proto__.color) //original color
+console.log(car2.__proto__.color) //original color
+console.log(car1.color)  // black
+console.log(car2.color) // original color
+
+ +
+

如果你没有使用 new 运算符, 构造函数会像其他的常规函数一样被调用,不会创建一个对象在这种情况下, this 的指向也是不一样的。

+
+ +

示例

+ +

对象类型和对象实例

+ +

假设你要创建一个汽车的对象类型。你希望这个类型叫做car,这个类型具备make, model, year等属性,要做到这些,你需要写这样一个函数:

+ +
function Car(make, model, year) {
+   this.make = make;
+   this.model = model;
+   this.year = year;
+}
+
+ +

现在,你可以如下所示创建一个 mycar 的对象:

+ +
var mycar = new Car("Eagle", "Talon TSi", 1993);
+ +

这段代码创建了 mycar 并给他的属性指定值,于是 mycar.make 的值为"Eagle", mycar.year 的值为1993,以此类推。

+ +

你可以通过调用 new 来创建任意个汽车对象。例如:

+ +
var kenscar = new Car("Nissan", "300ZX", 1992);
+ +

对象属性为其他对象

+ +

假设你定义了一个对象叫做 person

+ +
function Person(name, age, sex) {
+   this.name = name;
+   this.age = age;
+   this.sex = sex;
+}
+
+ +

然后实例化两个新的 person 对象如下:

+ +
var rand = new Person("Rand McNally", 33, "M");
+var ken = new Person("Ken Jones", 39, "M");
+
+ +

然后你可以重写 car 的定义,添加一个值为 person 对象的 owner 属性,如下:

+ +
function Car(make, model, year, owner) {
+   this.make = make;
+   this.model = model;
+   this.year = year;
+   this.owner = owner;
+}
+
+ +

为了实例化新的对象,你可以用如下代码:

+ +
var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
+var car2 = new Car("Nissan", "300ZX", 1992, ken);
+
+ +

创建对象时,并没有传字符串或数字给owner,而是传了对象 randken 。这个时候,你可以这样来获取 car2 的owner的name:

+ +
car2.owner.name
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ESDraft', '#sec-new-operator', 'The new Operator')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-new-operator', 'The new Operator')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.2.2', 'The new Operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.2.2', 'The new Operator')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-11.2.2', 'The new Operator')}}{{Spec2('ES1')}}初始定义。JavaScript 1.0实现。
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.new")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/nullish_coalescing_operator/index.html b/files/zh-cn/web/javascript/reference/operators/nullish_coalescing_operator/index.html new file mode 100644 index 0000000000..640d0fffa5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/nullish_coalescing_operator/index.html @@ -0,0 +1,158 @@ +--- +title: 空值合并运算符 +slug: Web/JavaScript/Reference/Operators/Nullish_coalescing_operator +tags: + - '??' + - JavaScript + - 参考 + - 空值 + - 空值合并操作符 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Nullish_coalescing_operator +--- +
{{JSSidebar("Operators")}}
+ +

空值合并操作符??)是一个逻辑操作符,当左侧的操作数为 {{jsxref("null")}} 或者 {{jsxref("undefined")}} 时,返回其右侧操作数,否则返回左侧操作数。

+ +

逻辑或操作符(||不同,逻辑或操作符会在左侧操作数为{{Glossary("Falsy", "假值")}}时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,'' 或 0)时。见下面的例子。

+ +
{{EmbedInteractiveExample("pages/js/expressions-nullishcoalescingoperator.html")}}
+ + + +

语法

+ +
leftExpr ?? rightExpr
+
+ +

示例

+ +

使用空值合并操作符

+ +

在这个例子中,我们使用空值合并操作符为常量提供默认值,保证常量不为 null 或者 undefined

+ +
const nullValue = null;
+const emptyText = ""; // 空字符串,是一个假值,Boolean("") === false
+const someNumber = 42;
+
+const valA = nullValue ?? "valA 的默认值";
+const valB = emptyText ?? "valB 的默认值";
+const valC = someNumber ?? 0;
+
+console.log(valA); // "valA 的默认值"
+console.log(valB); // ""(空字符串虽然是假值,但不是 null 或者 undefined)
+console.log(valC); // 42
+ +

为变量赋默认值

+ +

以前,如果想为一个变量赋默认值,通常的做法是使用逻辑或操作符(||):

+ +
let foo;
+
+//  foo is never assigned any value so it is still undefined
+let someDummyText = foo || 'Hello!';
+ +

然而,由于 || 是一个布尔逻辑运算符,左侧的操作数会被强制转换成布尔值用于求值。任何假值(0, '', NaN, null, undefined)都不会被返回。这导致如果你使用0''NaN作为有效值,就会出现不可预料的后果。

+ +
let count = 0;
+let text = "";
+
+let qty = count || 42;
+let message = text || "hi!";
+console.log(qty);     // 42,而不是 0
+console.log(message); // "hi!",而不是 ""
+ +

空值合并操作符可以避免这种陷阱,其只在第一个操作数为null 或 undefined 时(而不是其它假值)返回第二个操作数:

+ +
let myText = ''; // An empty string (which is also a falsy value)
+
+let notFalsyText = myText || 'Hello world';
+console.log(notFalsyText); // Hello world
+
+let preservingFalsy = myText ?? 'Hi neighborhood';
+console.log(preservingFalsy); // '' (as myText is neither undefined nor null)
+
+ +

短路

+ +

与 OR 和 AND 逻辑操作符相似,当左表达式不为 null 或 undefined 时,不会对右表达式进行求值。

+ +
function A() { console.log('函数 A 被调用了'); return undefined; }
+function B() { console.log('函数 B 被调用了'); return false; }
+function C() { console.log('函数 C 被调用了'); return "foo"; }
+
+console.log( A() ?? C() );
+// 依次打印 "函数 A 被调用了"、"函数 C 被调用了"、"foo"
+// A() 返回了 undefined,所以操作符两边的表达式都被执行了
+
+console.log( B() ?? C() );
+// 依次打印 "函数 B 被调用了"、"false"
+// B() 返回了 false(既不是 null 也不是 undefined)
+// 所以右侧表达式没有被执行
+
+ +

不能与 AND 或 OR 操作符共用

+ +

将 ?? 直接与 AND(&&)和 OR(||)操作符组合使用是不可取的。(译者注:应当是因为空值合并操作符和其他逻辑操作符之间的运算优先级/运算顺序是未定义的)这种情况下会抛出 SyntaxError

+ +
null || undefined ?? "foo"; // 抛出 SyntaxError
+true || undefined ?? "foo"; // 抛出 SyntaxError
+ +

但是,如果使用括号来显式表明运算优先级,是没有问题的:

+ +
(null || undefined ) ?? "foo"; // 返回 "foo"
+
+ +

与可选链式操作符(?.)的关系

+ +

空值合并操作符针对 undefined 与 null 这两个值,可选链式操作符(?. 也是如此。在这访问属性可能为 undefined 与 null 的对象时,可选链式操作符非常有用。

+ +
let foo = { someFooProp: "hi" };
+
+console.log(foo.someFooProp?.toUpperCase()); // "HI"
+console.log(foo.someBarProp?.toUpperCase()); // undefined
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#prod-Nulli', 'nullish coalescing expression')}}Stage 4
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.nullish_coalescing")}}

+ +

Implementation Progress

+ +

The following table provides a daily implementation status for this feature, because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in Test262, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.

+ +
{{EmbedTest262ReportResultsTable("coalesce-expression")}}
+ +

参见

+ + + +
+
+
diff --git a/files/zh-cn/web/javascript/reference/operators/object_initializer/index.html b/files/zh-cn/web/javascript/reference/operators/object_initializer/index.html new file mode 100644 index 0000000000..90fb0e6a8a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/object_initializer/index.html @@ -0,0 +1,314 @@ +--- +title: 对象初始化 +slug: Web/JavaScript/Reference/Operators/Object_initializer +tags: + - ECMAScript 2015 + - JavaScript + - Literal + - Methods + - Object + - Primary Expression + - computed + - mutation + - properties +translation_of: Web/JavaScript/Reference/Operators/Object_initializer +--- +
{{JsSidebar("Operators")}}
+ +

可以通过new Object() Object.create()方法,或者使用字面量标记(初始化标记)初始化对象。 一个对象初始化器,由花括号/大括号 ({}) 包含的一个由零个或多个对象属性名和其关联值组成的一个逗号分隔的列表构成。

+ +

语法

+ +
var o = {};
+var o = {a: 'foo', b: 42, c: {}};
+
+var a = 'foo', b = 42, c = {};
+var o = {a: a, b: b, c: c};
+
+var o = {
+  property: function ([parameters]) {},
+  get property() {},
+  set property(value) {}
+};
+ +

ECMAScript 2015 的新标记

+ +

请参考兼容性表格获取这些标记的支持信息。在不被支持的环境中,这些标记将造成语法错误。

+ +
// Shorthand property names (ES2015)
+var a = 'foo', b = 42, c = {};
+var o = {a, b, c};
+
+// Shorthand method names (ES2015)
+var o = {
+  property([parameters]) {}
+};
+
+// Computed property names (ES2015)
+var prop = 'foo';
+var o = {
+  [prop]: 'hey',
+  ['b' + 'ar']: 'there'
+};
+ +

描述

+ +

对象初始化是一个描述{{jsxref("Object","对象")}}初始化过程的表达式。对象初始化是由一组描述对象的属性组成。属性的值可以是{{Glossary("primitive","原始")}}类型,也可以是其他对象。

+ +

创建对象

+ +

没有属性的空对象可以用以下方式创建:

+ +
let obj = {};
+ +

不过,字面 初始化 标记的优势在于,可以用内含属性的花括号快速创建对象。简单地编写一个逗号分隔的键值对的类别。如下代码创建了一个含三个属性的对象,键分别为 "foo", "age" 和 "baz"。这些键对应的值,分别是字符串“bar”,数字42和另一个对象。

+ +
let obj = {
+  foo: "bar",
+  age: 42,
+  baz: { myProp: 12 },
+}
+ +

属性访问

+ +

创建对象后,可以读取或者修改它。对象属性可以用下标小圆点标记或者方括号标记访问。参考属性访问 获取更多信息。

+ +
object.foo; // "bar"
+object["age"]; // 42
+
+object.foo = "baz";
+
+ +

属性定义

+ +

上面学习了如何用初始化标记对象属性。经常能遇到希望将代码中的变量放到对象中的情况。可能遇到如下代码:

+ +
var a = "foo",
+    b = 42,
+    c = {};
+
+var o = {
+  a: a,
+  b: b,
+  c: c
+};
+ +

在 ECMAScript 2015 中,有更简短的标记可以实现同样的效果:

+ +
var a = 'foo',
+    b = 42,
+    c = {};
+
+// Shorthand property names (ES2015)
+var o = {a, b, c};
+
+// In other words,
+console.log((o.a === {a}.a)); // true
+ +

重复属性名

+ +

属性使用了同样的名称时,后面的属性会覆盖前面的属性。

+ +
var a = {x: 1, x: 2};
+console.log(a); // { x: 2}
+
+ +

在 ECMAScript 5 严格模式的代码中, 重复的属性名会被当做{{jsxref("SyntaxError")}}。引入计算的属性名以后,属性名会在运行时出现重复。ECMAScript 2015 移除了这个限制。

+ +
function haveES6DuplicatePropertySemantics(){
+  "use strict";
+  try {
+    ({ prop: 1, prop: 2 });
+
+    // No error thrown, duplicate property names allowed in strict mode
+    return true;
+  } catch (e) {
+    // Error thrown, duplicates prohibited in strict mode
+    return false;
+  }
+}
+ +

方法定义

+ +

对象属性也可以是一个函数gettersetter方法。

+ +
var o = {
+  property: function ([parameters]) {},
+  get property() {},
+  set property(value) {},
+};
+ +

ECMAScript 2015引入了一种简短写法, "function" 关键字也可以丢掉。

+ +
// Shorthand method names (ES6)
+var o = {
+  property([parameters]) {},
+  get property() {},
+  set property(value) {},
+  * generator() {}
+};
+ +

ECMAScript 2015 提供了一种简明地定义以生成器函数作为值的属性的方法。

+ +
var o = {
+  * generator() {
+    ...........
+  }
+};
+ +

ECMAScript 5 中可以这样书写(需要注意的是 ES5 没有生成器):

+ +
var o = {
+  generatorMethod: function *() {
+    ...........
+  }
+};
+ +

获取更多信息和范例,请参考 method definitions

+ +

计算属性名

+ +

从ECMAScript 2015开始,对象初始化语法开始支持计算属性名。其允许在[]中放入表达式,计算结果可以当做属性名。这种用法和用方括号访问属性非常类似,也许你已经用来读取和设置属性了。现在同样的语法也可以用于对象字面值了:

+ +
// Computed property names (ES6)
+var i = 0;
+var a = {
+  ["foo" + ++i]: i,
+  ["foo" + ++i]: i,
+  ["foo" + ++i]: i
+};
+
+console.log(a.foo1); // 1
+console.log(a.foo2); // 2
+console.log(a.foo3); // 3
+
+var param = 'size';
+var config = {
+  [param]: 12,
+  ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4
+};
+
+console.log(config); // { size: 12, mobileSize: 4 }
+ +

扩展属性

+ +

 

+ +

ECMAScript 提案(第3阶段)的剩余/扩展属性扩展属性添加到对象文字。它将自己提供的对象的枚举属性复制到一个新的对象上。

+ +

使用比{{jsxref("Object.assign()")}}更短的语法,可以轻松克隆(不包括原型)或合并对象。

+ +

 

+ +
var obj1 = { foo: 'bar', x: 42 };
+var obj2 = { foo: 'baz', y: 13 };
+
+var clonedObj = { ...obj1 };
+// Object { foo: "bar", x: 42 }
+
+var mergedObj = { ...obj1, ...obj2 };
+// Object { foo: "baz", x: 42, y: 13 }
+
+ +

请注意,{{jsxref("Object.assign()")}}会触发setter,而展开操作符则不会。

+ +

变更原型

+ +

定义属性为__proto__: 值"__proto__": 值 时,不会创建名为__proto__属性。如果给出的值是对象或者null,那么对象的[[Prototype]]会被设置为给出的值。(如果给出的值不是对象也不是null,那么对象的原型不会改变。)

+ +
var obj1 = {};
+assert(Object.getPrototypeOf(obj1) === Object.prototype);
+
+var obj2 = { __proto__: null };
+assert(Object.getPrototypeOf(obj2) === null);
+
+var protoObj = {};
+var obj3 = { "__proto__": protoObj };
+assert(Object.getPrototypeOf(obj3) === protoObj);
+
+var obj4 = { __proto__: "not an object or null" };
+assert(Object.getPrototypeOf(obj4) === Object.prototype);
+assert(!obj4.hasOwnProperty("__proto__"));
+
+ +

在对象字面值中,仅有一次变更原型的机会;多次变更原型,会被视为语法错误。

+ +

不使用冒号标记的属性定义,不会变更对象的原型;而是和其他具有不同名字的属性一样是普通属性定义。

+ +
var __proto__ = "variable";
+
+var obj1 = { __proto__ };
+assert(Object.getPrototypeOf(obj1) === Object.prototype);
+assert(obj1.hasOwnProperty("__proto__"));
+assert(obj1.__proto__ === "variable");
+
+var obj2 = { __proto__() { return "hello"; } };
+assert(obj2.__proto__() === "hello");
+
+var obj3 = { ["__prot" + "o__"]: 17 };
+assert(obj3.__proto__ === 17);
+
+ +

对象字面量表示法与JSON

+ +

对象字面量表示法和 JavaScript Object Notation(JSON)是不同的。虽然他们看起来相似,不同点有:

+ + + +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}initial definition.
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}getter and setter added.
{{SpecName('ES2015', '#sec-object-initializer', 'Object Initializer')}}{{Spec2('ES2015')}}Shorthand method/property names and computed property names added.
{{SpecName('ESDraft', '#sec-object-initializer', 'Object Initializer')}}{{Spec2('ESDraft')}} 
Rest/Spread Properties for ECMAScript DraftStage 3 draft.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.object_initializer")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/operator_precedence/index.html b/files/zh-cn/web/javascript/reference/operators/operator_precedence/index.html new file mode 100644 index 0000000000..de411354aa --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/operator_precedence/index.html @@ -0,0 +1,351 @@ +--- +title: 运算符优先级 +slug: Web/JavaScript/Reference/Operators/Operator_Precedence +tags: + - JavaScript + - 优先级 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence +--- +
{{jsSidebar("Operators")}}
+ +

运算符的优先级决定了表达式中运算执行的先后顺序,优先级高的运算符最先被执行。

+ +
{{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}}
+ + + +

关联性

+ +

关联性决定了拥有相同优先级的运算符的执行顺序。考虑下面这个表达式:

+ +
a OP b OP c;
+
+ +

左关联(左到右)相当于把左边的子表达式加上小括号(a OP b) OP c,右关联(右到左)相当于a OP (b OP c)。赋值运算符是右关联的,所以你可以这么写:

+ +
a = b = 5; 
+ +

结果 a 和 b 的值都会成为5。这是因为赋值运算符的返回结果就是赋值运算符右边的那个值,具体过程是:b被赋值为5,然后a也被赋值为 b=5 的返回值,也就是5。

+ +

示例

+ +
3 > 2 && 2 > 1
+// return true
+
+3 > 2 > 1
+// 返回 false,因为 3 > 2 是 true,并且 true > 1 is false
+// 加括号可以更清楚:(3 > 2) > 1
+
+ +

汇总表

+ +

下面的表将所有运算符按照优先级的不同从高(20)到低(1)排列。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
优先级运算类型关联性运算符
21{{jsxref("Operators/Grouping", "圆括号")}}n/a(不相关)( … )
20{{jsxref("Operators/Property_Accessors","成员访问", "#点符号表示法")}}从左到右… . …
{{jsxref("Operators/Property_Accessors","需计算的成员访问", "#括号表示法")}}从左到右… [ … ]
{{jsxref("Operators/new","new")}} (带参数列表)n/anew … ( … )
函数调用从左到右… ( … )
可选链(Optional chaining)从左到右?.
19new (无参数列表)从右到左new …
18后置递增(运算符在后)n/a
+  
… ++
后置递减(运算符在后)… --
17逻辑非从右到左! …
按位非~ …
一元加法+ …
一元减法- …
前置递增++ …
前置递减-- …
typeoftypeof …
voidvoid …
deletedelete …
awaitawait …
16从右到左… ** …
15乘法从左到右
+  
… * …
除法… / …
取模… % …
14加法从左到右
+  
… + …
减法… - …
13按位左移从左到右… << …
按位右移… >> …
无符号右移… >>> …
12小于从左到右… < …
小于等于… <= …
大于… > …
大于等于… >= …
in… in …
instanceof… instanceof …
11等号从左到右
+  
… == …
非等号… != …
全等号… === …
非全等号… !== …
10按位与从左到右… & …
9按位异或从左到右… ^ …
8按位或从左到右… | …
7逻辑与从左到右… && …
6逻辑或从左到右… || …
5空值合并从左到右… ?? …
4条件运算符从右到左… ? … : …
3赋值从右到左… = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
… &&= …
… ||= …
… ??= …
2yield从右到左yield …
yield*yield* …
1展开运算符n/a... …
0逗号从左到右… , …
diff --git a/files/zh-cn/web/javascript/reference/operators/property_accessors/index.html b/files/zh-cn/web/javascript/reference/operators/property_accessors/index.html new file mode 100644 index 0000000000..f989fe1f22 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/property_accessors/index.html @@ -0,0 +1,153 @@ +--- +title: 属性访问器 +slug: Web/JavaScript/Reference/Operators/Property_Accessors +tags: + - JavaScript + - Operator + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/Property_Accessors +--- +
{{jsSidebar("Operators")}}
+ +

属性访问器提供了两种方式用于访问一个对象的属性,它们分别是点号和方括号。

+ +
{{EmbedInteractiveExample("pages/js/expressions-propertyaccessors.html")}}
+ + + +

语法

+ +
object.property
+object['property']
+
+ +

描述

+ +

我们可以将对象看做是一个关联数组(或者:映射字典哈希表查询表)。这个数组中的键就是这个对象中属性的名称。通常,当我们提及一个对象的属性时,会对属性与方法之间做个对比。然而,属性与方法之间的区别并不大。一个方法就是一个可以被调用的属性而已,例如一个指向函数 Function 实例的引用可以作为对象属性的值。

+ +

访问对象属性有两种方式:点号表示法和方括号表示法。

+ +

点号表示法

+ +
get = object.property;
+object.property = set;
+
+ +

以上代码中,property必须是一个有效的 JavaScript 标识符,例如,一串字母数字字符,也包括下划线及美元符号,但不能以数字作为开头。比如,object.$1是合法的,而 object.1是无效不合法的。

+ +
document.createElement('pre');
+
+ +

在上述代码块中,document中存在一个名为"createElement"的方法并且被调用了。

+ +

如果对数字字面量使用方法,并且数字文字没有指数且没有小数点,请在方法调用之前的点之前留出空格,以防止点被解释为小数点。

+ +
77 .toExponential();
+// 或
+77
+.toExponential();
+// 或
+(77).toExponential();
+// 或
+77..toExponential();
+// 或
+77.0.toExponential();
+// 因为 77. === 77.0,没有歧义(no ambiguity)
+
+ +

方括号表示法

+ +
get = object[property_name];
+object[property_name] = set;
+
+ +

property_name 是一个字符串。该字符串不一定是一个合法的标识符;它可以是任意值,例如,"1foo","!bar!",甚至是 " "(一个空格)。

+ +
document['createElement']('pre');
+
+ +

这里的代码的功能跟上一个例子的作用是相同的。

+ +

括号之前允许有空格。

+ +
document ['createElement']('pre');
+
+ +

属性名称

+ +

属性名称必须是字符串或符号 Symbol。这意味着非字符串对象不能用来作为一个对象属性的键。任何非字符串对象,包括 Number,都会通过 toString 方法,被转换成一个字符串。

+ +
var object = {};
+object['1'] = 'value';
+console.log(object[1]);
+
+ +

上述代码的输出为"value",因为 1 被类型转换为'1'。

+ +
var foo = {unique_prop: 1}, bar = {unique_prop: 2}, object = {};
+object[foo] = 'value';
+console.log(object[bar]);
+
+ +

上述的代码的输出也是 "value",由于对象 foo 和 bar 都会被转成相同的字符串。在SpiderMonkey JavaScript 引擎中,这个字符串是 "[object Object]"。

+ +

方法绑定

+ +

一个方法没有绑定到对象上,那就意味着这个方法是不起作用的。特别要注意的是,在一个方法中this对象并不是固定的,例如,this不需要指向包含当前方法的对象。this可通过函数调用被传递过去的值所替换。详见方法绑定

+ +

注意eval

+ +

在那些可通过方括号表示法替换的场景下,JavaScript 新手在使用eval 经常会犯错。例如,下面的语法经常在很多代码中找到。

+ +
x = eval('document.forms.form_name.elements.' + strFormControl + '.value');
+
+ +

eval 的性能较差,且有安全风险。在任何时候都应该避免使用。而且,此时 strFormControl 必须是一个合法的标识符, 这在一些表单控件的 name、ID 值之中并不是必要的。所以,使用括号来代替会更好一些:

+ +
x = document.forms["form_name"].elements[strFormControl].value;
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-property-accessors', 'Property Accessors')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-property-accessors', 'Property Accessors')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-11.2.1', 'Property Accessors')}}{{Spec2('ES5.1')}} 
{{SpecName('ES1', '#sec-11.2.1', 'Property Accessors')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.property_accessors")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/remainder_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/remainder_assignment/index.html new file mode 100644 index 0000000000..a9d015e467 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/remainder_assignment/index.html @@ -0,0 +1,56 @@ +--- +title: Remainder assignment (%=) +slug: Web/JavaScript/Reference/Operators/Remainder_assignment +translation_of: Web/JavaScript/Reference/Operators/Remainder_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The remainder assignment operator (%=) divides a variable by the value of the right operand and assigns the remainder to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-remainder-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x %= y
+Meaning:  x  = x % y
+ +

Examples

+ +

Using remainder assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar %= 2     // 1
+bar %= 'foo' // NaN
+bar %= 0     // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.remainder_assignment")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/right_shift/index.html b/files/zh-cn/web/javascript/reference/operators/right_shift/index.html new file mode 100644 index 0000000000..267a2c0ccc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/right_shift/index.html @@ -0,0 +1,75 @@ +--- +title: Right shift (>>) +slug: Web/JavaScript/Reference/Operators/Right_shift +translation_of: Web/JavaScript/Reference/Operators/Right_shift +--- +
{{jsSidebar("Operators")}}
+ +

The right shift operator (>>) shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Copies of the leftmost bit are shifted in from the left. Since the new leftmost bit has the same value as the previous leftmost bit, the sign bit (the leftmost bit) does not change. Hence the name "sign-propagating".

+ +
{{EmbedInteractiveExample("pages/js/expressions-right-shift.html")}}
+ + + +

语法

+ +
a >> b
+
+ +

Description

+ +

This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Copies of the leftmost bit are shifted in from the left. Since the new leftmost bit has the same value as the previous leftmost bit, the sign bit (the leftmost bit) does not change. Hence the name "sign-propagating".

+ +

For example, 9 >> 2 yields 2:

+ +
.    9 (base 10): 00000000000000000000000000001001 (base 2)
+                  --------------------------------
+9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

Likewise, -9 >> 2 yields -3, because the sign is preserved:

+ +
.    -9 (base 10): 11111111111111111111111111110111 (base 2)
+                   --------------------------------
+-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
+
+ +

Examples

+ +

Using right shift

+ +
 9 >> 2; //  2
+-9 >> 2; // -3
+
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.right_shift")}}

+ +

See also

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/right_shift_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/right_shift_assignment/index.html new file mode 100644 index 0000000000..d4163c0f4d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/right_shift_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: Right shift assignment (>>=) +slug: Web/JavaScript/Reference/Operators/Right_shift_assignment +translation_of: Web/JavaScript/Reference/Operators/Right_shift_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The right shift assignment operator (>>=) moves the specified amount of bits to the right and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-right-shift-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x >>= y
+Meaning:  x   = x >> y
+ +

Examples

+ +

Using right shift assignment

+ +
let a = 5; //   (00000000000000000000000000000101)
+a >>= 2;   // 1 (00000000000000000000000000000001)
+
+let b = -5; //  (-00000000000000000000000000000101)
+b >>= 2;  // -2 (-00000000000000000000000000000010)
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.right_shift_assignment")}}

+ +

See also

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/spread_syntax/index.html b/files/zh-cn/web/javascript/reference/operators/spread_syntax/index.html new file mode 100644 index 0000000000..4bb2ff8b45 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/spread_syntax/index.html @@ -0,0 +1,245 @@ +--- +title: 展开语法 +slug: Web/JavaScript/Reference/Operators/Spread_syntax +tags: + - ECMAScript2015 + - Iterator + - JavaScript + - 展开 +translation_of: Web/JavaScript/Reference/Operators/Spread_syntax +--- +
{{jsSidebar("Operators")}}
+ +
展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。(译者注: 字面量一般指 [1, 2, 3] 或者 {name: "mdn"} 这种简洁的构造方式)
+ +
{{EmbedInteractiveExample("pages/js/expressions-spreadsyntax.html")}}
+ + + +

语法

+ +

函数调用:

+ +
myFunction(...iterableObj);
+ +

字面量数组构造或字符串:

+ +
[...iterableObj, '4', ...'hello', 6];
+ +

构造字面量对象时,进行克隆或者属性拷贝(ECMAScript 2018规范新增特性):

+ +
let objClone = { ...obj };
+ +

示例

+ +

在函数调用时使用展开语法

+ +

等价于apply的方式

+ +

如果想将数组元素迭代为函数参数,一般使用{{jsxref( "Function.prototype.apply")}} 的方式进行调用

+ +
function myFunction(x, y, z) { }
+var args = [0, 1, 2];
+myFunction.apply(null, args);
+ +

有了展开语法,可以这样写:

+ +
function myFunction(x, y, z) { }
+var args = [0, 1, 2];
+myFunction(...args);
+ +

所有参数都可以通过展开语法来传值,也不限制多次使用展开语法。

+ +
function myFunction(v, w, x, y, z) { }
+var args = [0, 1];
+myFunction(-1, ...args, 2, ...[3]);
+ +

在 new 表达式中应用

+ +

使用 new 关键字来调用构造函数时,不能直接使用数组+ apply 的方式(apply 执行的是调用 [[Call]] , 而不是构造 [[Construct]])。当然, 有了展开语法, 将数组展开为构造函数的参数就很简单了:

+ +
var dateFields = [1970, 0, 1]; // 1970年1月1日
+var d = new Date(...dateFields);
+
+ +

如果不使用展开语法, 想将数组元素传给构造函数, 实现方式可能是这样的

+ +
function applyAndNew(constructor, args) {
+   function partial () {
+      return constructor.apply(this, args);
+   };
+   if (typeof constructor.prototype === "object") {
+      partial.prototype = Object.create(constructor.prototype);
+   }
+   return partial;
+}
+
+
+function myConstructor () {
+   console.log("arguments.length: " + arguments.length);
+   console.log(arguments);
+   this.prop1="val1";
+   this.prop2="val2";
+};
+
+var myArguments = ["hi", "how", "are", "you", "mr", null];
+var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);
+
+console.log(new myConstructorWithArguments);
+// (myConstructor构造函数中):           arguments.length: 6
+// (myConstructor构造函数中):           ["hi", "how", "are", "you", "mr", null]
+// ("new myConstructorWithArguments"中): {prop1: "val1", prop2: "val2"}
+ +

构造字面量数组时使用展开语法

+ +

构造字面量数组时更给力!

+ +

没有展开语法的时候,只能组合使用 push, splice, concat 等方法,来将已有数组元素变成新数组的一部分。有了展开语法,  通过字面量方式, 构造新数组会变得更简单、更优雅:

+ +
var parts = ['shoulders', 'knees'];
+var lyrics = ['head', ...parts, 'and', 'toes']; 
+// ["head", "shoulders", "knees", "and", "toes"]
+
+ +

和参数列表的展开类似,  ... 在构造字面量数组时, 可以在任意位置多次使用.

+ +

数组拷贝(copy)

+ +
var arr = [1, 2, 3];
+var arr2 = [...arr]; // like arr.slice()
+arr2.push(4);
+
+// arr2 此时变成 [1, 2, 3, 4]
+// arr 不受影响
+
+ +

提示: 实际上, 展开语法和 {{jsxref("Object.assign()")}} 行为一致, 执行的都是浅拷贝(只遍历一层)。如果想对多维数组进行深拷贝, 下面的示例就有些问题了。

+ +
var a = [[1], [2], [3]];
+var b = [...a];
+b.shift().shift(); // 1
+// Now array a is affected as well: [[2], [3]]
+
+ +

连接多个数组

+ +

{{jsxref("Array.concat")}} 函数常用于将一个数组连接到另一个数组的后面。如果不使用展开语法, 代码可能是下面这样的:

+ +
var arr1 = [0, 1, 2];
+var arr2 = [3, 4, 5];
+// 将 arr2 中所有元素附加到 arr1 后面并返回
+var arr3 = arr1.concat(arr2);
+ +

使用展开语法:

+ +
var arr1 = [0, 1, 2];
+var arr2 = [3, 4, 5];
+var arr3 = [...arr1, ...arr2];
+
+ +

{{jsxref("Array.unshift")}} 方法常用于在数组的开头插入新元素/数组.  不使用展开语法, 示例如下:

+ +
var arr1 = [0, 1, 2];
+var arr2 = [3, 4, 5];
+// 将 arr2 中的元素插入到 arr1 的开头
+Array.prototype.unshift.apply(arr1, arr2) // arr1 现在是 [3, 4, 5, 0, 1, 2]
+ +

如果使用展开语法, 代码如下:  [请注意, 这里使用展开语法创建了一个新的 arr1 数组,  {{jsxref("Array.unshift")}} 方法则是修改了原本存在的 arr1 数组]:

+ +
var arr1 = [0, 1, 2];
+var arr2 = [3, 4, 5];
+arr1 = [...arr2, ...arr1]; // arr1 现在为 [3, 4, 5, 0, 1, 2]
+
+ +

构造字面量对象时使用展开语法

+ +

Rest/Spread Properties for ECMAScript 提议(stage 4) 对 字面量对象 增加了展开特性。其行为是, 将已有对象的所有可枚举(enumerable)属性拷贝到新构造的对象中.

+ +

浅拷贝(Shallow-cloning, 不包含 prototype) 和对象合并, 可以使用更简短的展开语法。而不必再使用 {{jsxref("Object.assign()")}} 方式.

+ +
var obj1 = { foo: 'bar', x: 42 };
+var obj2 = { foo: 'baz', y: 13 };
+
+var clonedObj = { ...obj1 };
+// 克隆后的对象: { foo: "bar", x: 42 }
+
+var mergedObj = { ...obj1, ...obj2 };
+// 合并后的对象: { foo: "baz", x: 42, y: 13 }
+
+ +

提示: {{jsxref("Object.assign()")}} 函数会触发 setters,而展开语法则不会。

+ + + +

提示: 不能替换或者模拟 {{jsxref("Object.assign()")}} 函数:

+ +
var obj1 = { foo: 'bar', x: 42 };
+var obj2 = { foo: 'baz', y: 13 };
+const merge = ( ...objects ) => ( { ...objects } );
+
+var mergedObj = merge ( obj1, obj2);
+// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }
+
+var mergedObj = merge ( {}, obj1, obj2);
+// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }
+ +

在这段代码中, 展开操作符(spread operator)并没有按预期的方式执行:  而是先将多个解构变为剩余参数(rest parameter), 然后再将剩余参数展开为字面量对象.

+ + + +

只能用于可迭代对象

+ +

在数组或函数参数中使用展开语法时, 该语法只能用于 可迭代对象

+ +
var obj = {'key1': 'value1'};
+var array = [...obj]; // TypeError: obj is not iterable
+
+ +

展开多个值

+ +

在函数调用时使用展开语法,请注意不能超过 JavaScript 引擎限制的最大参数个数。更多详细信息,请参考: apply()

+ +

剩余语法(剩余参数)

+ +

剩余语法(Rest syntax) 看起来和展开语法完全相同,不同点在于, 剩余参数用于解构数组和对象。从某种意义上说,剩余语法与展开语法是相反的:展开语法将数组展开为其中的各个元素,而剩余语法则是将多个元素收集起来并“凝聚”为单个元素。 请参考: 剩余参数

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-array-initializer')}}{{Spec2('ES2015')}}Defined in several sections of the specification: Array Initializer, Argument Lists
{{SpecName('ESDraft', '#sec-array-initializer')}}{{Spec2('ESDraft')}}No changes.
{{SpecName('ESDraft', '#sec-object-initializer')}}{{Spec2('ESDraft')}}Defined in Object Initializer
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.spread")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/strict_equality/index.html b/files/zh-cn/web/javascript/reference/operators/strict_equality/index.html new file mode 100644 index 0000000000..125b67c168 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/strict_equality/index.html @@ -0,0 +1,101 @@ +--- +title: Strict equality (===) +slug: Web/JavaScript/Reference/Operators/Strict_equality +translation_of: Web/JavaScript/Reference/Operators/Strict_equality +--- +
{{jsSidebar("Operators")}}
+ +

全等运算符 (===) 会检查它的两个操作数是否相等,并且返回一个布尔值结果。与相等运算符不同,全等运算符总是认为不同类型的操作数是不同的。

+ +
{{EmbedInteractiveExample("pages/js/expressions-strict-equality.html")}}
+ + + +

语法

+ +
x === y
+ +

描述

+ +

全等运算符(===!==)使用全等比较算法来比较两个操作数。

+ + + +

全等运算符与相等运算符==)最显著的区别是,如果操作数的类型不同,== 运算符会在比较之前尝试将它们转换为相同的类型。

+ +

例子

+ +

比较相同类型的操作数

+ +
console.log("hello" === "hello");   // true
+console.log("hello" === "hola");    // false
+
+console.log(3 === 3);               // true
+console.log(3 === 4);               // false
+
+console.log(true === true);         // true
+console.log(true === false);        // false
+
+console.log(null === null);         // true
+ +

比较不同类型的操作数

+ +
console.log("3" === 3);           // false
+
+console.log(true === 1);          // false
+
+console.log(null === undefined);  // false
+ +

比较对象

+ +
const object1 = {
+  name: "hello"
+}
+
+const object2 = {
+  name: "hello"
+}
+
+console.log(object1 === object2);  // false
+console.log(object1 === object1);  // true
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.strict_equality")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/strict_inequality/index.html b/files/zh-cn/web/javascript/reference/operators/strict_inequality/index.html new file mode 100644 index 0000000000..e71f28c100 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/strict_inequality/index.html @@ -0,0 +1,95 @@ +--- +title: 严格不相等 (!==) +slug: Web/JavaScript/Reference/Operators/Strict_inequality +translation_of: Web/JavaScript/Reference/Operators/Strict_inequality +--- +
{{jsSidebar("Operators")}}
+ +

严格不等式操作符(!==)检查它的两个对象是否不相等,返回一个布尔结果。与不等式运算符不同,严格不等式运算符总是认为不同类型的对象是不同的。

+ +
{{EmbedInteractiveExample("pages/js/expressions-strict-equality.html")}}
+ + + +

语法

+ +
x !== y
+ +

描述

+ +

严格不等式运算符检查其对象是否不相等。它是严格相等运算符的否定,因此下面两行总是会给出相同的结果:

+ +
x !== y
+
+!(x === y)
+ +

有关比较算法的详细信息,请参阅严格相等运算符的页面。

+ +

与严格相等运算符一样,严格不等运算符始终认为不同类型的对象是不同的:

+ +
3 !== "3"; // true
+ +

示例

+ +

比较相同类型的对象

+ +
console.log("hello" !== "hello");   // false
+console.log("hello" !== "hola");    // true
+
+console.log(3 !== 3);               // false
+console.log(3 !== 4);               // true
+
+console.log(true !== true);         // false
+console.log(true !== false);        // true
+
+console.log(null !== null);         // false
+ +

比较不同类型的对象

+ +
console.log("3" !== 3);           // true
+
+console.log(true !== 1);          // true
+
+console.log(null !== undefined);  // true
+ +

比较Object对象

+ +
const object1 = {
+  name: "hello"
+}
+
+const object2 = {
+  name: "hello"
+}
+
+console.log(object1 !== object2);  // true
+console.log(object1 !== object1);  // false
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.strict_inequality")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/subtraction/index.html b/files/zh-cn/web/javascript/reference/operators/subtraction/index.html new file mode 100644 index 0000000000..6bb33366e8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/subtraction/index.html @@ -0,0 +1,67 @@ +--- +title: Subtraction (-) +slug: Web/JavaScript/Reference/Operators/Subtraction +translation_of: Web/JavaScript/Reference/Operators/Subtraction +--- +
{{jsSidebar("Operators")}}
+ +

The subtraction operator (-) subtracts the two operands, producing their difference.

+ +
{{EmbedInteractiveExample("pages/js/expressions-subtraction.html")}}
+ +
+ + + +

语法

+ +
Operator: x - y
+
+ +

Examples

+ +

Subtraction with numbers

+ +
5 - 3     // 2
+3 - 5     // -2
+ +

Subtraction with non-numbers

+ +
'foo' - 3 // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-subtraction-operator-minus', 'Subtraction operator')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.subtraction")}}

+ +

See also

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/subtraction_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/subtraction_assignment/index.html new file mode 100644 index 0000000000..8286c2010b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/subtraction_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: Subtraction assignment (-=) +slug: Web/JavaScript/Reference/Operators/Subtraction_assignment +translation_of: Web/JavaScript/Reference/Operators/Subtraction_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The subtraction assignment operator (-=) subtracts the value of the right operand from a variable and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-subtraction-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x -= y
+Meaning:  x  = x - y
+ +

Examples

+ +

Using subtraction assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar -= 2     // 3
+bar -= 'foo' // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.subtraction_assignment")}}

+ +

See also

+ + + +

+ +

diff --git a/files/zh-cn/web/javascript/reference/operators/super/index.html b/files/zh-cn/web/javascript/reference/operators/super/index.html new file mode 100644 index 0000000000..6681f759ab --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/super/index.html @@ -0,0 +1,184 @@ +--- +title: super +slug: Web/JavaScript/Reference/Operators/super +tags: + - Classes + - ECMAScript 2015 + - JavaScript + - Operator +translation_of: Web/JavaScript/Reference/Operators/super +--- +
{{jsSidebar("Operators")}}
+ +

super关键字用于访问和调用一个对象的父对象上的函数。

+ +

super.propsuper[expr]表达式在对象字面量任何方法定义中都是有效的。

+ +

语法

+ +
super([arguments]);
+// 调用 父对象/父类 的构造函数
+
+super.functionOnParent([arguments]);
+// 调用 父对象/父类 上的方法
+
+ +

描述

+ +

在构造函数中使用时,super关键字将单独出现,并且必须在使用this关键字之前使用。super关键字也可以用来调用父对象上的函数。

+ +

示例

+ +

在类中使用super

+ +

以下代码片段来自于 classes sample

+ +
class Polygon {
+  constructor(height, width) {
+    this.name = 'Rectangle';
+    this.height = height;
+    this.width = width;
+  }
+  sayName() {
+    console.log('Hi, I am a ', this.name + '.');
+  }
+  get area() {
+    return this.height * this.width;
+  }
+  set area(value) {
+    this._area = value;
+  }
+}
+
+class Square extends Polygon {
+  constructor(length) {
+    this.height; // ReferenceError,super 需要先被调用!
+
+    // 这里,它调用父类的构造函数的,
+    // 作为Polygon 的 height, width
+    super(length, length);
+
+    // 注意: 在派生的类中, 在你可以使用'this'之前, 必须先调用super()。
+    // 忽略这, 这将导致引用错误。
+    this.name = 'Square';
+  }
+}
+
+ +

调用父类上的静态方法

+ +

你也可以用 super 调用父类的静态方法

+ +
class Rectangle {
+  constructor() {}
+  static logNbSides() {
+    return 'I have 4 sides';
+  }
+}
+
+class Square extends Rectangle {
+  constructor() {}
+  static logDescription() {
+    return super.logNbSides() + ' which are all equal';
+  }
+}
+Square.logDescription(); // 'I have 4 sides which are all equal'
+ +

删除 super 上的属性将抛出异常

+ +

你不能使用 delete 操作符 加 super.prop 或者 super[expr] 去删除父类的属性,这样做会抛出 {{jsxref("ReferenceError")}}。

+ +
class Base {
+  constructor() {}
+  foo() {}
+}
+class Derived extends Base {
+  constructor() {}
+  delete() {
+    delete super.foo; // this is bad
+  }
+}
+
+new Derived().delete(); // ReferenceError: invalid delete involving 'super'.
+ +

super.prop 不能覆写不可写属性

+ +

当使用 {{jsxref("Object.defineProperty")}} 定义一个属性为不可写时,super将不能重写这个属性的值。

+ +
class X {
+  constructor() {
+    Object.defineProperty(this, 'prop', {
+      configurable: true,
+      writable: false,
+      value: 1
+    });
+  }
+}
+
+class Y extends X {
+  constructor() {
+    super();
+  }
+  foo() {
+    super.prop = 2;   // Cannot overwrite the value.
+  }
+}
+
+var y = new Y();
+y.foo(); // TypeError: "prop" is read-only
+console.log(y.prop); // 1
+ +

在对象字面量中使用super.prop

+ +

Super也可以在object initializer / literal 符号中使用。在下面的例子中,两个对象各定义了一个方法。在第二个对象中, 我们使用super调用了第一个对象中的方法。 当然,这需要我们先利用 {{jsxref("Object.setPrototypeOf()")}} 设置obj2的原型为obj1,然后才能够使用super调用 obj1上的method1

+ +
var obj1 = {
+  method1() {
+    console.log("method 1");
+  }
+}
+
+var obj2 = {
+  method2() {
+   super.method1();
+  }
+}
+
+Object.setPrototypeOf(obj2, obj1);
+obj2.method2(); // logs "method 1"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-super-keyword', 'super')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-super-keyword', 'super')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.super")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/this/index.html b/files/zh-cn/web/javascript/reference/operators/this/index.html new file mode 100644 index 0000000000..a3378079ac --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/this/index.html @@ -0,0 +1,498 @@ +--- +title: this +slug: Web/JavaScript/Reference/Operators/this +tags: + - JavaScript + - Operator + - Primary Expressions + - Reference + - this + - 参考 +translation_of: Web/JavaScript/Reference/Operators/this +--- +
{{jsSidebar("Operators")}}
+ +

与其他语言相比,函数的 this 关键字在 JavaScript 中的表现略有不同,此外,在严格模式和非严格模式之间也会有一些差别。

+ +

在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定)。this 不能在执行期间被赋值,并且在每次函数被调用时 this 的值也可能会不同。ES5 引入了 bind 方法来设置函数的 this 值,而不用考虑函数如何被调用的。ES2015 引入了箭头函数,箭头函数不提供自身的 this 绑定(this 的值将保持为闭合词法上下文的值)。

+ +

{{EmbedInteractiveExample("pages/js/expressions-this.html")}}

+ +

语法

+ +
this
+ +

+ +

当前执行上下文(global、function 或 eval)的一个属性,在非严格模式下,总是指向一个对象,在严格模式下可以是任意值。

+ +

描述

+ +

全局上下文

+ +

无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。

+ +
// 在浏览器中, window 对象同时也是全局对象:
+console.log(this === window); // true
+
+a = 37;
+console.log(window.a); // 37
+
+this.b = "MDN";
+console.log(window.b)  // "MDN"
+console.log(b)         // "MDN"
+ +
+

Note: 你可以使用 {{jsxref("globalThis")}} 获取全局对象,无论你的代码是否在当前上下文运行。

+
+ +

函数上下文

+ +

在函数内部,this的值取决于函数被调用的方式。

+ +

因为下面的代码不在严格模式下,且 this 的值不是由该调用设置的,所以 this 的值默认指向全局对象,浏览器中就是 {{domxref("Window", "window")}}。

+ +
function f1(){
+  return this;
+}
+//在浏览器中:
+f1() === window;   //在浏览器中,全局对象是window
+
+//在Node中:
+f1() === globalThis;
+
+ +

然而,在严格模式下,如果进入执行环境时没有设置 this 的值,this 会保持为 undefined,如下:

+ +
function f2(){
+  "use strict"; // 这里是严格模式
+  return this;
+}
+
+f2() === undefined; // true
+
+ +
在第二个例子中,this 应是 undefined,因为 f2 是被直接调用的,而不是作为对象的属性或方法调用的(如 window.f2())。有一些浏览器最初在支持严格模式时没有正确实现这个功能,于是它们错误地返回了window对象。
+ +

如果要想把 this 的值从一个环境传到另一个,就要用 call 或者apply 方法,如下方的示例所示。

+ +

类上下文

+ +

this 在  中的表现与在函数中类似,因为类本质上也是函数,但也有一些区别和注意事项。

+ +

在类的构造函数中,this 是一个常规对象。类中所有非静态的方法都会被添加到 this 的原型中:

+ +
class Example {
+  constructor() {
+    const proto = Object.getPrototypeOf(this);
+    console.log(Object.getOwnPropertyNames(proto));
+  }
+  first(){}
+  second(){}
+  static third(){}
+}
+
+new Example(); // ['constructor', 'first', 'second']
+ +
+

注意:静态方法不是 this 的属性,它们只是类自身的属性。

+
+ +

派生类

+ +

不像基类的构造函数,派生类的构造函数没有初始的 this 绑定。在构造函数中调用 {{jsxref("Operators/super", "super()")}} 会生成一个 this 绑定,并相当于执行如下代码,Base为基类:

+ +
this = new Base();
+ +
+

警告:在调用 super() 之前引用 this 会抛出错误。

+
+ +

派生类不能在调用 super() 之前返回,除非其构造函数返回的是一个对象,或者根本没有构造函数。

+ +
class Base {}
+class Good extends Base {}
+class AlsoGood extends Base {
+  constructor() {
+    return {a: 5};
+  }
+}
+class Bad extends Base {
+  constructor() {}
+}
+
+new Good();
+new AlsoGood();
+new Bad(); // ReferenceError
+ +

示例

+ +

函数上下文中的 this

+ +
// An object can be passed as the first argument to call or apply and this will be bound to it.
+var obj = {a: 'Custom'};
+
+// We declare a variable and the variable is assigned to the global window as its property.
+var a = 'Global';
+
+function whatsThis() {
+  return this.a;  // The value of this is dependent on how the function is called
+}
+
+whatsThis();          // 'Global' as this in the function isn't set, so it defaults to the global/window object
+whatsThis.call(obj);  // 'Custom' as this in the function is set to obj
+whatsThis.apply(obj); // 'Custom' as this in the function is set to obj
+
+ +

this 和对象转换

+ +
function add(c, d) {
+  return this.a + this.b + c + d;
+}
+
+var o = {a: 1, b: 3};
+
+// 第一个参数是用作“this”的对象
+// 其余参数用作函数的参数
+add.call(o, 5, 7); // 16
+
+// 第一个参数是用作“this”的对象
+// 第二个参数是一个数组,数组中的两个成员用作函数参数
+add.apply(o, [10, 20]); // 34
+
+ +

在非严格模式下使用 call 和 apply 时,如果用作 this 的值不是对象,则会被尝试转换为对象。null 和 undefined 被转换为全局对象。原始值如 7 或 'foo' 会使用相应构造函数转换为对象。因此 7 会被转换为 new Number(7) 生成的对象,字符串 'foo' 会转换为 new String('foo') 生成的对象。

+ +
function bar() {
+  console.log(Object.prototype.toString.call(this));
+}
+
+bar.call(7);     // [object Number]
+bar.call('foo'); // [object String]
+bar.call(undefined); // [object global]
+ +

bind方法

+ +

ECMAScript 5 引入了 {{jsxref("Function.prototype.bind()")}}。调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的。

+ +
function f(){
+  return this.a;
+}
+
+var g = f.bind({a:"azerty"});
+console.log(g()); // azerty
+
+var h = g.bind({a:'yoo'}); // bind只生效一次!
+console.log(h()); // azerty
+
+var o = {a:37, f:f, g:g, h:h};
+console.log(o.a, o.f(), o.g(), o.h()); // 37, 37, azerty, azerty
+
+ +

箭头函数

+ +

箭头函数中,this与封闭词法环境的this保持一致。在全局代码中,它将被设置为全局对象:

+ +
var globalObject = this;
+var foo = (() => this);
+console.log(foo() === globalObject); // true
+ +
+

注意:如果将this传递给callbind、或者apply来调用箭头函数,它将被忽略。不过你仍然可以为调用添加参数,不过第一个参数(thisArg)应该设置为null

+
+ +
// 接着上面的代码
+// 作为对象的一个方法调用
+var obj = {foo: foo};
+console.log(obj.foo() === globalObject); // true
+
+// 尝试使用call来设定this
+console.log(foo.call(obj) === globalObject); // true
+
+// 尝试使用bind来设定this
+foo = foo.bind(obj);
+console.log(foo() === globalObject); // true
+ +

无论如何,foo 的 this 被设置为他被创建时的环境(在上面的例子中,就是全局对象)。这同样适用于在其他函数内创建的箭头函数:这些箭头函数的this被设置为封闭的词法环境的。

+ +
// 创建一个含有bar方法的obj对象,
+// bar返回一个函数,
+// 这个函数返回this,
+// 这个返回的函数是以箭头函数创建的,
+// 所以它的this被永久绑定到了它外层函数的this。
+// bar的值可以在调用中设置,这反过来又设置了返回函数的值。
+var obj = {
+  bar: function() {
+    var x = (() => this);
+    return x;
+  }
+};
+
+// 作为obj对象的一个方法来调用bar,把它的this绑定到obj。
+// 将返回的函数的引用赋值给fn。
+var fn = obj.bar();
+
+// 直接调用fn而不设置this,
+// 通常(即不使用箭头函数的情况)默认为全局对象
+// 若在严格模式则为undefined
+console.log(fn() === obj); // true
+
+// 但是注意,如果你只是引用obj的方法,
+// 而没有调用它
+var fn2 = obj.bar;
+// 那么调用箭头函数后,this指向window,因为它从 bar 继承了this。
+console.log(fn2()() == window); // true
+ +

在上面的例子中,一个赋值给了 obj.bar的函数(称为匿名函数 A),返回了另一个箭头函数(称为匿名函数 B)。因此,在 A 调用时,函数B的this被永久设置为obj.bar(函数A)的this。当返回的函数(函数B)被调用时,它this始终是最初设置的。在上面的代码示例中,函数B的this被设置为函数A的this,即obj,所以即使被调用的方式通常将其设置为 undefined 或全局对象(或者如前面示例中的其他全局执行环境中的方法),它的 this 也仍然是 obj 。

+ +

作为对象的方法

+ +

当函数作为对象里的方法被调用时,this 被设置为调用该函数的对象。

+ +

下面的例子中,当 o.f() 被调用时,函数内的 this 将绑定到 o 对象。

+ +
var o = {
+  prop: 37,
+  f: function() {
+    return this.prop;
+  }
+};
+
+console.log(o.f()); // 37
+
+ +

请注意,这样的行为完全不会受函数定义方式或位置的影响。在前面的例子中,我们在定义对象o的同时,将其中的函数定义为成员 f 。但是,我们也可以先定义函数,然后再将其附属到o.f。这样做的结果是一样的:

+ +
var o = {prop: 37};
+
+function independent() {
+  return this.prop;
+}
+
+o.f = independent;
+
+console.log(o.f()); // 37
+
+ +

这表明函数是从 o 的 f 成员调用的才是重点。

+ +

同样,this 的绑定只受最接近的成员引用的影响。在下面的这个例子中,我们把一个方法g当作对象o.b的函数调用。在这次执行期间,函数中的this将指向o.b。事实证明,这与他是对象 o 的成员没有多大关系,最近的引用才是最重要的。

+ +
o.b = {g: independent, prop: 42};
+console.log(o.b.g()); // 42
+ +

原型链中的 this

+ +

对于在对象原型链上某处定义的方法,同样的概念也适用。如果该方法存在于一个对象的原型链上,那么 this 指向的是调用这个方法的对象,就像该方法就在这个对象上一样。

+ +
var o = {
+  f: function() {
+    return this.a + this.b;
+  }
+};
+var p = Object.create(o);
+p.a = 1;
+p.b = 4;
+
+console.log(p.f()); // 5
+
+ +

在这个例子中,对象 p 没有属于它自己的 f 属性,它的 f 属性继承自它的原型。虽然最终是在 o 中找到 f 属性的,这并没有关系;查找过程首先从 p.f 的引用开始,所以函数中的 this 指向p。也就是说,因为f是作为p的方法调用的,所以它的this指向了p。这是 JavaScript 的原型继承中的一个有趣的特性。

+ +

getter 与 setter 中的 this

+ +

再次,相同的概念也适用于当函数在一个 getter 或者 setter 中被调用。用作 getter 或 setter 的函数都会把 this 绑定到设置或获取属性的对象。

+ +
function sum() {
+  return this.a + this.b + this.c;
+}
+
+var o = {
+  a: 1,
+  b: 2,
+  c: 3,
+  get average() {
+    return (this.a + this.b + this.c) / 3;
+  }
+};
+
+Object.defineProperty(o, 'sum', {
+    get: sum, enumerable: true, configurable: true});
+
+console.log(o.average, o.sum); // logs 2, 6
+
+ +

作为构造函数

+ +

当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。

+ +
+

虽然构造函数返回的默认值是 this 所指的那个对象,但它仍可以手动返回其他的对象(如果返回值不是一个对象,则返回 this 对象)。

+
+ +
/*
+ * 构造函数这样工作:
+ *
+ * function MyConstructor(){
+ *   // 函数实体写在这里
+ *   // 根据需要在this上创建属性,然后赋值给它们,比如:
+ *   this.fum = "nom";
+ *   // 等等...
+ *
+ *   // 如果函数具有返回对象的return语句,
+ *   // 则该对象将是 new 表达式的结果。
+ *   // 否则,表达式的结果是当前绑定到 this 的对象。
+ *   //(即通常看到的常见情况)。
+ * }
+ */
+
+function C(){
+  this.a = 37;
+}
+
+var o = new C();
+console.log(o.a); // logs 37
+
+
+function C2(){
+  this.a = 37;
+  return {a:38};
+}
+
+o = new C2();
+console.log(o.a); // logs 38
+
+ +

在刚刚的例子中(C2),因为在调用构造函数的过程中,手动的设置了返回对象,与this绑定的默认对象被丢弃了。(这基本上使得语句 “this.a = 37;”成了“僵尸”代码,实际上并不是真正的“僵尸”,这条语句执行了,但是对于外部没有任何影响,因此完全可以忽略它)。

+ +

作为一个DOM事件处理函数

+ +

当函数被用作事件处理函数时,它的 this 指向触发事件的元素(一些浏览器在使用非 addEventListener 的函数动态地添加监听函数时不遵守这个约定)。

+ +
// 被调用时,将关联的元素变成蓝色
+function bluify(e){
+  console.log(this === e.currentTarget); // 总是 true
+
+  // 当 currentTarget 和 target 是同一个对象时为 true
+  console.log(this === e.target);
+  this.style.backgroundColor = '#A5D9F3';
+}
+
+// 获取文档中的所有元素的列表
+var elements = document.getElementsByTagName('*');
+
+// 将bluify作为元素的点击监听函数,当元素被点击时,就会变成蓝色
+for(var i=0 ; i<elements.length ; i++){
+  elements[i].addEventListener('click', bluify, false);
+}
+ +

作为一个内联事件处理函数

+ +

当代码被内联 on-event 处理函数 调用时,它的this指向监听器所在的DOM元素:

+ +
<button onclick="alert(this.tagName.toLowerCase());">
+  Show this
+</button>
+
+ +

上面的 alert 会显示 button。注意只有外层代码中的 this 是这样设置的:

+ +
<button onclick="alert((function(){return this})());">
+  Show inner this
+</button>
+
+ +

在这种情况下,没有设置内部函数的 this,所以它指向 global/window 对象(即非严格模式下调用的函数未设置 this 时指向的默认对象)。

+ +

类中的this

+ +

和其他普通函数一样,方法中的 this 值取决于它们如何被调用。有时,改写这个行为,让类中的 this 值总是指向这个类实例会很有用。为了做到这一点,可在构造函数中绑定类方法:

+ +
class Car {
+  constructor() {
+    // Bind sayBye but not sayHi to show the difference
+    this.sayBye = this.sayBye.bind(this);
+  }
+  sayHi() {
+    console.log(`Hello from ${this.name}`);
+  }
+  sayBye() {
+    console.log(`Bye from ${this.name}`);
+  }
+  get name() {
+    return 'Ferrari';
+  }
+}
+
+class Bird {
+  get name() {
+    return 'Tweety';
+  }
+}
+
+const car = new Car();
+const bird = new Bird();
+
+// The value of 'this' in methods depends on their caller
+car.sayHi(); // Hello from Ferrari
+bird.sayHi = car.sayHi;
+bird.sayHi(); // Hello from Tweety
+
+// For bound methods, 'this' doesn't depend on the caller
+bird.sayBye = car.sayBye;
+bird.sayBye();  // Bye from Ferrari
+ +
+

注意:类内部总是严格模式。调用一个 this 值为 undefined 的方法会抛出错误。

+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-this-keyword', 'The this keyword')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-this-keyword', 'The this keyword')}}{{Spec2('ES2015')}}
{{SpecName('ES5.1', '#sec-11.1.1', 'The this keyword')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.1.1', 'The this keyword')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-11.1.1', 'The this keyword')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.this")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/typeof/index.html b/files/zh-cn/web/javascript/reference/operators/typeof/index.html new file mode 100644 index 0000000000..9ecc801903 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/typeof/index.html @@ -0,0 +1,286 @@ +--- +title: typeof +slug: Web/JavaScript/Reference/Operators/typeof +tags: + - JavaScript + - Operator + - Unary +translation_of: Web/JavaScript/Reference/Operators/typeof +--- +

{{jsSidebar("Operators")}}

+ +

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

+ +
{{EmbedInteractiveExample("pages/js/expressions-typeof.html")}}
+ + + +

语法

+ +

typeof 运算符后接操作数:

+ +
typeof operand
+typeof(operand)
+
+ +

参数

+ +

operand

+ +
+
一个表示对象或{{Glossary("Primitive", "原始值")}}的表达式,其类型将被返回。
+
+ +

描述

+ +

下表总结了 typeof 可能的返回值。有关类型和原始值的更多信息,可查看 JavaScript 数据结构 页面。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
类型结果
{{glossary("Undefined")}}"undefined"
{{glossary("Null")}}"object" (见{{anch("null", "下文")}})
{{glossary("Boolean")}}"boolean"
{{glossary("Number")}}"number"
{{glossary("BigInt")}}(ECMAScript 2020 新增)"bigint"
{{glossary("String")}}"string"
{{glossary("Symbol")}} (ECMAScript 2015 新增)"symbol"
宿主对象(由 JS 环境提供)取决于具体实现
{{glossary("Function")}} 对象 (按照 ECMA-262 规范实现 [[Call]])"function"
其他任何对象"object"
+ +

示例

+ +
// 数值
+typeof 37 === 'number';
+typeof 3.14 === 'number';
+typeof(42) === 'number';
+typeof Math.LN2 === 'number';
+typeof Infinity === 'number';
+typeof NaN === 'number'; // 尽管它是 "Not-A-Number" (非数值) 的缩写
+typeof Number(1) === 'number'; // Number 会尝试把参数解析成数值
+
+typeof 42n === 'bigint';
+
+
+// 字符串
+typeof '' === 'string';
+typeof 'bla' === 'string';
+typeof `template literal` === 'string';
+typeof '1' === 'string'; // 注意内容为数字的字符串仍是字符串
+typeof (typeof 1) === 'string'; // typeof 总是返回一个字符串
+typeof String(1) === 'string'; // String 将任意值转换为字符串,比 toString 更安全
+
+
+// 布尔值
+typeof true === 'boolean';
+typeof false === 'boolean';
+typeof Boolean(1) === 'boolean'; // Boolean() 会基于参数是真值还是虚值进行转换
+typeof !!(1) === 'boolean'; // 两次调用 ! (逻辑非) 操作符相当于 Boolean()
+
+
+// Symbols
+typeof Symbol() === 'symbol';
+typeof Symbol('foo') === 'symbol';
+typeof Symbol.iterator === 'symbol';
+
+
+// Undefined
+typeof undefined === 'undefined';
+typeof declaredButUndefinedVariable === 'undefined';
+typeof undeclaredVariable === 'undefined';
+
+
+// 对象
+typeof {a: 1} === 'object';
+
+// 使用 Array.isArray 或者 Object.prototype.toString.call
+// 区分数组和普通对象
+typeof [1, 2, 4] === 'object';
+
+typeof new Date() === 'object';
+typeof /regex/ === 'object'; // 历史结果请参阅正则表达式部分
+
+
+// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
+typeof new Boolean(true) === 'object';
+typeof new Number(1) === 'object';
+typeof new String('abc') === 'object';
+
+// 函数
+typeof function() {} === 'function';
+typeof class C {} === 'function'
+typeof Math.sin === 'function';
+
+ +

typeof null

+ +
// JavaScript 诞生以来便如此
+typeof null === 'object';
+ +

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"。(参考来源

+ +

曾有一个 ECMAScript 的修复提案(通过选择性加入的方式),但被拒绝了。该提案会导致 typeof null === 'null'

+ +

使用 new 操作符

+ +
// 除 Function 外的所有构造函数的类型都是 'object'
+var str = new String('String');
+var num = new Number(100);
+
+typeof str; // 返回 'object'
+typeof num; // 返回 'object'
+
+var func = new Function();
+
+typeof func; // 返回 'function'
+ +

语法中的括号

+ +
// 括号有无将决定表达式的类型。
+var iData = 99;
+
+typeof iData + ' Wisen'; // 'number Wisen'
+typeof (iData + ' Wisen'); // 'string'
+ +

正则表达式

+ +

对正则表达式字面量的类型判断在某些浏览器中不符合标准:

+ +
typeof /s/ === 'function'; // Chrome 1-12 , 不符合 ECMAScript 5.1
+typeof /s/ === 'object'; // Firefox 5+ , 符合 ECMAScript 5.1
+
+ +

错误

+ +

在 ECMAScript 2015 之前,typeof 总能保证对任何所给的操作数返回一个字符串。即便是没有声明的标识符,typeof 也能返回 'undefined'。使用 typeof 永远不会抛出错误。

+ +

但在加入了块级作用域的 let 和 const 之后,在其被声明之前对块中的 let 和 const 变量使用 typeof 会抛出一个 ReferenceError。块作用域变量在块的头部处于“暂存死区”,直至其被初始化,在这期间,访问变量将会引发错误。

+ +
typeof undeclaredVariable === 'undefined';
+
+typeof newLetVariable; // ReferenceError
+typeof newConstVariable; // ReferenceError
+typeof newClass; // ReferenceError
+
+let newLetVariable;
+const newConstVariable = 'hello';
+class newClass{};
+ +

例外

+ +

当前所有的浏览器都暴露了一个类型为 undefined 的非标准宿主对象 {{domxref("document.all")}}。

+ +
typeof document.all === 'undefined';
+
+ +

尽管规范允许为非标准的外来对象自定义类型标签,但它要求这些类型标签与已有的不同。document.all 的类型标签为 'undefined' 的例子在 Web 领域中被归类为对原 ECMA JavaScript 标准的“故意侵犯”。

+ +

Real-world usage

+ +

typeof is very useful, but it's not as versatile as might be required. For example, typeof([]) , is 'object', as well as typeof(new Date()), typeof(/abc/), etc.

+ +

For greater specificity in checking types, a typeof wrapper for usage in production-level code would be as follows (provided obj exists):

+ +
  function type(obj, fullClass) {
+
+    // get toPrototypeString() of obj (handles all types)
+    // Early JS environments return '[object Object]' for null, so it's best to directly check for it.
+    if (fullClass) {
+        return (obj === null) ? '[object Null]' : Object.prototype.toString.call(obj);
+    }
+    if (obj == null) { return (obj + '').toLowerCase(); } // implicit toString() conversion
+
+    var deepType = Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
+    if (deepType === 'generatorfunction') { return 'function' }
+
+    // Prevent overspecificity (for example, [object HTMLDivElement], etc).
+    // Account for functionish Regexp (Android <=2.3), functionish <object> element (Chrome <=57, Firefox <=52), etc.
+    // String.prototype.match is universally supported.
+
+    return deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol)$/) ? deepType :
+       (typeof obj === 'object' || typeof obj === 'function') ? 'object' : typeof obj;
+  }
+ +

For checking non-existent variables that would otherwise throw a {{JSxRef("ReferenceError")}}, use typeof nonExistentVar === 'undefined'.

+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-typeof-operator', 'The typeof Operator')}}
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.operators.typeof")}}

+ +

IE 特别提示

+ +

在 IE 6, 7 和 8 上,很多宿主对象是对象而不是函数。例如:

+ +
typeof alert === 'object'
+
+ +
+ +

相关链接

+ + + +
+
+
diff --git a/files/zh-cn/web/javascript/reference/operators/unary_negation/index.html b/files/zh-cn/web/javascript/reference/operators/unary_negation/index.html new file mode 100644 index 0000000000..2170b92c53 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/unary_negation/index.html @@ -0,0 +1,73 @@ +--- +title: Unary negation (-) +slug: Web/JavaScript/Reference/Operators/Unary_negation +translation_of: Web/JavaScript/Reference/Operators/Unary_negation +--- +
{{jsSidebar("Operators")}}
+ +

The unary negation operator (-) precedes its operand and negates it.

+ +
{{EmbedInteractiveExample("pages/js/expressions-unary-negation.html")}}
+ + + +

语法

+ +
Operator: -x
+
+ +

Examples

+ +

Negating numbers

+ +
const x = 3;
+const y = -x;
+
+// y = -3
+// x = 3
+
+ +

Negating non-numbers

+ +

The unary negation operator can convert a non-number into a number.

+ +
const x = "4";
+const y = -x;
+
+// y = -4
+
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-unary-minus-operator', 'Unary negation operator')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.unary_negation")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/unary_plus/index.html b/files/zh-cn/web/javascript/reference/operators/unary_plus/index.html new file mode 100644 index 0000000000..9f3b818df9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/unary_plus/index.html @@ -0,0 +1,75 @@ +--- +title: Unary plus (+) +slug: Web/JavaScript/Reference/Operators/Unary_plus +translation_of: Web/JavaScript/Reference/Operators/Unary_plus +--- +
{{jsSidebar("Operators")}}
+ +

The unary plus operator (+) precedes its operand and evaluates to its operand but attempts to convert it into a number, if it isn't already.

+ +
{{EmbedInteractiveExample("pages/js/expressions-unary-plus.html", "taller")}}
+ + + +

语法

+ +
Operator: +x
+
+ +

Description

+ +

Although unary negation (-) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number. It can convert string representations of integers and floats, as well as the non-string values true, false, and null. Integers in both decimal and hexadecimal (0x-prefixed) formats are supported. Negative numbers are supported (though not for hex). Using the operator on BigInt values throws a TypeError. If it cannot parse a particular value, it will evaluate to {{jsxref("NaN")}}.

+ +

Examples

+ +

Usage with numbers

+ +
const x = 1;
+const y = -1;
+
+console.log(+x);
+// 1
+console.log(+y);
+// -1
+ +

Usage with non-numbers

+ +
+true  // 1
++false // 0
++null  // 0
++function(val){ return val } // NaN
++1n    // throws TypeError: Cannot convert BigInt value to number
+
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-unary-plus-operator', 'Unary plus operator')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.unary_plus")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift/index.html b/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift/index.html new file mode 100644 index 0000000000..f40a28e8b0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift/index.html @@ -0,0 +1,71 @@ +--- +title: Unsigned right shift (>>>) +slug: Web/JavaScript/Reference/Operators/Unsigned_right_shift +translation_of: Web/JavaScript/Reference/Operators/Unsigned_right_shift +--- +
{{jsSidebar("Operators")}}
+ +

The unsigned right shift operator (>>>) (zero-fill right shift) shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left. The sign bit becomes 0, so the result is always non-negative. Unlike the other bitwise operators, zero-fill right shift returns an unsigned 32-bit integer.

+ +
{{EmbedInteractiveExample("pages/js/expressions-unsigned-right-shift.html")}}
+ + + +

语法

+ +
a >>> b
+
+ +

描述

+ +

This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left. The sign bit becomes 0, so the result is always non-negative. Unlike the other bitwise operators, zero-fill right shift returns an unsigned 32-bit integer.

+ +

For non-negative numbers, zero-fill right shift and sign-propagating right shift yield the same result. For example, 9 >>> 2 yields 2, the same as 9 >> 2:

+ +
.     9 (base 10): 00000000000000000000000000001001 (base 2)
+                   --------------------------------
+9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

However, this is not the case for negative numbers. For example, -9 >>> 2 yields 1073741821, which is different than -9 >> 2 (which yields -3):

+ +
.     -9 (base 10): 11111111111111111111111111110111 (base 2)
+                    --------------------------------
+-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
+
+ +

例子

+ +

Using unsigned right shift

+ +
 9 >>> 2; // 2
+-9 >>> 2; // 1073741821
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.unsigned_right_shift")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift_assignment/index.html new file mode 100644 index 0000000000..76379358c0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift_assignment/index.html @@ -0,0 +1,55 @@ +--- +title: Unsigned right shift assignment (>>>=) +slug: Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment +translation_of: Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment +--- +
{{jsSidebar("Operators")}}
+ +

The unsigned right shift assignment operator (>>>=) moves the specified amount of bits to the right and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-unsigned-right-shift-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x >>>= y
+Meaning:  x    = x >>> y
+ +

例子

+ +

Using unsigned right shift assignment

+ +
let a = 5; //   (00000000000000000000000000000101)
+a >>>= 2;  // 1 (00000000000000000000000000000001)
+
+let b = -5; // (-00000000000000000000000000000101)
+b >>>= 2;   // 1073741822 (00111111111111111111111111111110)
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.unsigned_right_shift_assignment")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/void/index.html b/files/zh-cn/web/javascript/reference/operators/void/index.html new file mode 100644 index 0000000000..b67110459a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/void/index.html @@ -0,0 +1,114 @@ +--- +title: void 运算符 +slug: Web/JavaScript/Reference/Operators/void +tags: + - JavaScript + - Unary +translation_of: Web/JavaScript/Reference/Operators/void +--- +
{{jsSidebar("Operators")}}
+ +

void 运算符 对给定的表达式进行求值,然后返回 {{jsxref("Global_Objects/undefined", "undefined")}}。

+ +

语法

+ +
void expression
+ +

描述

+ +

这个运算符能向期望一个表达式的值是{{jsxref("Global_Objects/undefined", "undefined")}}的地方插入会产生副作用的表达式。

+ +

void 运算符通常只用于获取 undefined的原始值,一般使用void(0)(等同于void 0)。在上述情况中,也可以使用全局变量{{jsxref("Global_Objects/undefined", "undefined")}} 来代替(假定其仍是默认值)。

+ +

立即调用的函数表达式

+ +

在使用立即执行的函数表达式时,可以利用 void 运算符让 JavaScript 引擎把一个function关键字识别成函数表达式而不是函数声明(语句)。

+ +
void function iife() {
+    var bar = function () {};
+    var baz = function () {};
+    var foo = function () {
+        bar();
+        baz();
+     };
+    var biz = function () {};
+
+    foo();
+    biz();
+}();
+
+ +

JavaScript URIs

+ +

当用户点击一个以 javascript: URI 时,它会执行URI中的代码,然后用返回的值替换页面内容,除非返回的值是{{jsxref("Global_Objects/undefined", "undefined")}}。void运算符可用于返回{{jsxref("Global_Objects/undefined", "undefined")}}。例如:

+ +
<a href="javascript:void(0);">
+  这个链接点击之后不会做任何事情,如果去掉 void(),
+  点击之后整个页面会被替换成一个字符 0。
+</a>
+<p> chrome中即使<a href="javascript:0;">也没变化,firefox中会变成一个字符串0 </p>
+<a href="javascript:void(document.body.style.backgroundColor='green');">
+  点击这个链接会让页面背景变成绿色。
+</a>
+
+ +

注意,虽然这么做是可行的,但利用 javascript: 伪协议来执行 JavaScript 代码是不推荐的,推荐的做法是为链接元素绑定事件。

+ +

在箭头函数中避免泄漏

+ +

箭头函数标准中,允许在函数体不使用括号来直接返回值。 如果右侧调用了一个原本没有返回值的函数,其返回值改变后,则会导致非预期的副作用。 安全起见,当函数返回值是一个不会被使用到的时候,应该使用 void 运算符,来确保返回 {{jsxref("Global_Objects/undefined", "undefined")}}(如下方示例),这样,当 API 改变时,并不会影响箭头函数的行为。

+ +
button.onclick = () => void doSomething();
+ +

确保了当 doSomething 的返回值从 {{jsxref("Global_Objects/undefined", "undefined")}} 变为 true 的时候,不会改变函数的行为

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-void-operator', 'The void Operator')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-void-operator', 'The void Operator')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.4.2', 'The void Operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.4.2', 'The void Operator')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-11.4.2', 'The void Operator')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.void")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/yield/index.html b/files/zh-cn/web/javascript/reference/operators/yield/index.html new file mode 100644 index 0000000000..58e9adfc00 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/yield/index.html @@ -0,0 +1,104 @@ +--- +title: yield +slug: Web/JavaScript/Reference/Operators/yield +tags: + - ECMAScript 2015 + - Generators + - Iterator + - JavaScript + - Operator +translation_of: Web/JavaScript/Reference/Operators/yield +--- +
{{jsSidebar("Operators")}}
+ +

yield 关键字用来暂停和恢复一个生成器函数(({{jsxref("Statements/function*", "function*")}} 或遗留的生成器函数)。

+ +

语法

+ +
[rv] = yield [expression];
+ +
+
expression
+
定义通过迭代器协议从生成器函数返回的值。如果省略,则返回undefined
+
rv
+
+

返回传递给生成器的next()方法的可选值,以恢复其执行。

+
+
+ +

描述

+ +

yield关键字使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。

+ +

yield关键字实际返回一个IteratorResult对象,它有两个属性,valuedonevalue属性是对yield表达式求值的结果,而donefalse,表示生成器函数尚未完全完成。

+ +

一旦遇到 yield 表达式,生成器的代码将被暂停运行,直到生成器的 next() 方法被调用。每次调用生成器的next()方法时,生成器都会恢复执行,直到达到以下某个值:

+ + + +

如果将参数传递给生成器的next()方法,则该值将成为生成器当前yield操作返回的值。

+ +

在生成器的代码路径中的yield运算符,以及通过将其传递给{{jsxref("Generator.prototype.next()")}}指定新的起始值的能力之间,生成器提供了强大的控制力。

+ +

示例

+ +

以下代码是一个生成器函数的声明。

+ +
function* countAppleSales () {
+  var saleList = [3, 7, 5];
+  for (var i = 0; i < saleList.length; i++) {
+    yield saleList[i];
+  }
+}
+ +

一旦生成器函数已定义,可以通过构造一个迭代器来使用它。

+ +
var appleStore = countAppleSales(); // Generator { }
+console.log(appleStore.next()); // { value: 3, done: false }
+console.log(appleStore.next()); // { value: 7, done: false }
+console.log(appleStore.next()); // { value: 5, done: false }
+console.log(appleStore.next()); // { value: undefined, done: true }
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#', 'Yield')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#', 'Yield')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.yield")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/yield_star_/index.html b/files/zh-cn/web/javascript/reference/operators/yield_star_/index.html new file mode 100644 index 0000000000..c53be56902 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/yield_star_/index.html @@ -0,0 +1,162 @@ +--- +title: yield* +slug: Web/JavaScript/Reference/Operators/yield* +tags: + - ECMAScript 2015 + - Generators + - Iterable + - Iterator + - JavaScript + - Operator + - Reference +translation_of: Web/JavaScript/Reference/Operators/yield* +--- +
{{jsSidebar("Operators")}}
+ +

 yield* 表达式用于委托给另一个{{jsxref("Statements/function*", "generator")}} 或可迭代对象。

+ +

语法

+ +
 yield* [[expression]];
+ +
+
expression
+
返回一个可迭代对象的表达式。
+
+ +

描述

+ +

yield* 表达式迭代操作数,并产生它返回的每个值。

+ +

yield* 表达式本身的值是当迭代器关闭时返回的值(即donetrue时)。

+ +

示例

+ +

委托给其他生成器

+ +

以下代码中,g1() yield 出去的每个值都会在 g2() 的 next() 方法中返回,就像那些 yield 语句是写在 g2() 里一样。

+ +
function* g1() {
+  yield 2;
+  yield 3;
+  yield 4;
+}
+
+function* g2() {
+  yield 1;
+  yield* g1();
+  yield 5;
+}
+
+var iterator = g2();
+
+console.log(iterator.next()); // { value: 1, done: false }
+console.log(iterator.next()); // { value: 2, done: false }
+console.log(iterator.next()); // { value: 3, done: false }
+console.log(iterator.next()); // { value: 4, done: false }
+console.log(iterator.next()); // { value: 5, done: false }
+console.log(iterator.next()); // { value: undefined, done: true }
+
+ +

委托给其他可迭代对象

+ +

除了生成器对象这一种可迭代对象,yield* 还可以 yield 其它任意的可迭代对象,比如说数组、字符串、arguments 对象等等。

+ +
function* g3() {
+  yield* [1, 2];
+  yield* "34";
+  yield* arguments;
+}
+
+var iterator = g3(5, 6);
+
+console.log(iterator.next()); // { value: 1, done: false }
+console.log(iterator.next()); // { value: 2, done: false }
+console.log(iterator.next()); // { value: "3", done: false }
+console.log(iterator.next()); // { value: "4", done: false }
+console.log(iterator.next()); // { value: 5, done: false }
+console.log(iterator.next()); // { value: 6, done: false }
+console.log(iterator.next()); // { value: undefined, done: true }
+
+ +

yield* 表达式的值

+ +

yield* 是一个表达式,不是语句,所以它会有自己的值。

+ +
function* g4() {
+  yield* [1, 2, 3];
+  return "foo";
+}
+
+var result;
+
+function* g5() {
+  result = yield* g4();
+}
+
+var iterator = g5();
+
+console.log(iterator.next()); // { value: 1, done: false }
+console.log(iterator.next()); // { value: 2, done: false }
+console.log(iterator.next()); // { value: 3, done: false }
+console.log(iterator.next()); // { value: undefined, done: true },
+                              // 此时 g4() 返回了 { value: "foo", done: true }
+
+console.log(result);          // "foo"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#', 'Yield')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#', 'Yield')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.yield_star")}}

+ +

Firefox 特别提示

+ + + +

相关链接

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" "b/files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" new file mode 100644 index 0000000000..276296ccd7 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" @@ -0,0 +1,81 @@ +--- +title: 取余 (%) +slug: Web/JavaScript/Reference/Operators/取余 +tags: + - JavaScript + - Language feature + - Operator + - Reference +translation_of: Web/JavaScript/Reference/Operators/Remainder +--- +
{{jsSidebar("Operators")}}
+ +

当一个操作数除以第二个操作数时,取余运算符(%)返回剩余的余数。它与被除数的符号保持一致。

+ +
{{EmbedInteractiveExample("pages/js/expressions-remainder.html")}}
+ +
+ + + +

语法

+ +
Operator: var1 % var2
+
+ +

示例

+ +

被除数为正数

+ +
 12 % 5  //  2
+ 1 % -2 //  1
+ 1 % 2  //  1
+ 2 % 3  //  2
+5.5 % 2 // 1.5
+
+ +

被除数为负数

+ +
-12 % 5 // -2
+-1 % 2  // -1
+-4 % 2  // -0
+ +

被除数为NaN

+ +
NaN % 2 // NaN
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Remainder operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.remainder")}}

+ +

相关链接

+ + + + diff --git "a/files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" "b/files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" new file mode 100644 index 0000000000..da2f04c775 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" @@ -0,0 +1,202 @@ +--- +title: 可选链操作符 +slug: Web/JavaScript/Reference/Operators/可选链 +tags: + - '?.' + - JavaScript + - Optional chaining (?.) + - Reference + - 参考 + - 可选链 + - 语言特性 + - 运算符 + - 链式调用 +translation_of: Web/JavaScript/Reference/Operators/Optional_chaining +--- +
{{JSSidebar("Operators")}}
+ +

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) ({{JSxRef("null")}} 或者 {{JSxRef("undefined")}}) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

+ +

当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。

+ +
{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html", "taller")}}
+ + + +

语法

+ +
obj?.prop
+obj?.[expr]
+arr?.[index]
+func?.(args)
+
+ +

描述

+ +

通过连接的对象的引用或函数可能是 undefinednull 时,可选链操作符提供了一种方法来简化被连接对象的值访问。

+ +

比如,思考一个存在嵌套结构的对象 obj。不使用可选链的话,查找一个深度嵌套的子属性时,需要验证之间的引用,例如:

+ +
let nestedProp = obj.first && obj.first.second;
+ +

为了避免报错,在访问obj.first.second之前,要保证 obj.first 的值既不是 null,也不是 undefined。如果只是直接访问 obj.first.second,而不对 obj.first 进行校验,则有可能抛出错误。

+ +

有了可选链操作符(?.),在访问 obj.first.second 之前,不再需要明确地校验 obj.first 的状态,再并用短路计算获取最终结果:

+ +
let nestedProp = obj.first?.second;
+ +

通过使用 ?. 操作符取代 . 操作符,JavaScript 会在尝试访问 obj.first.second 之前,先隐式地检查并确定 obj.first 既不是 null 也不是 undefined。如果obj.first null 或者 undefined,表达式将会短路计算直接返回 undefined

+ +

这等价于以下表达式,但实际上没有创建临时变量:

+ +
let temp = obj.first;
+let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);
+ +

可选链与函数调用

+ +

当尝试调用一个可能不存在的方法时也可以使用可选链。这将是很有帮助的,比如,当使用一个API的方法可能不可用时,要么因为实现的版本问题要么因为当前用户的设备不支持该功能。

+ +

函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。

+ +
let result = someInterface.customMethod?.();
+ +
+

注意: 如果存在一个属性名且不是函数, 使用 ?. 仍然会产生一个 {{JSxRef("TypeError")}} 异常 (x.y is not a function).

+
+ +
+

注意: 如果 someInterface 自身是 null 或者 undefined ,异常 {{JSxRef("TypeError")}} 仍会被抛出 someInterface is null 如果你希望允许 someInterface 也为 null 或者 undefined ,那么你需要像这样写 someInterface?.customMethod?.()

+
+ +

处理可选的回调函数或者事件处理器

+ +

如果使用解构赋值来解构的一个对象的回调函数或 fetch 方法,你可能得到不能当做函数直接调用的不存在的值,除非你已经校验了他们的存在性。使用?.的你可以忽略这些额外的校验:

+ +
//  ES2019的写法
+function doSomething(onContent, onError) {
+  try {
+    // ... do something with the data
+  }
+  catch (err) {
+    if (onError) { // 校验onError是否真的存在
+      onError(err.message);
+    }
+  }
+}
+
+ +
// 使用可选链进行函数调用
+function doSomething(onContent, onError) {
+  try {
+   // ... do something with the data
+  }
+  catch (err) {
+    onError?.(err.message); // 如果onError是undefined也不会有异常
+  }
+}
+
+ +

可选链和表达式

+ +

当使用方括号与属性名的形式来访问属性时,你也可以使用可选链操作符:

+ +
let nestedProp = obj?.['prop' + 'Name'];
+ +

可选链不能用于赋值

+ +
let object = {};
+object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
+ +

可选链访问数组元素

+ +
let arrayItem = arr?.[42];
+ +

例子

+ +

基本例子

+ +

如下的例子在一个不含 bar 成员的 Map 中查找 bar 成员的 name 属性,因此结果是 undefined

+ +
let myMap = new Map();
+myMap.set("foo", {name: "baz", desc: "inga"});
+
+let nameBar = myMap.get("bar")?.name;
+ +

短路计算

+ +

当在表达式中使用可选链时,如果左操作数是 nullundefined,表达式将不会被计算,例如:

+ +
let potentiallyNullObj = null;
+let x = 0;
+let prop = potentiallyNullObj?.[x++];
+
+console.log(x); // x 将不会被递增,依旧输出 0
+
+ +

连用可选链操作符

+ +

可以连续使用可选链读取多层嵌套结构:

+ +
let customer = {
+  name: "Carl",
+  details: {
+    age: 82,
+    location: "Paradise Falls" // details 的 address 属性未有定义
+  }
+};
+let customerCity = customer.details?.address?.city;
+
+// … 可选链也可以和函数调用一起使用
+let duration = vacations.trip?.getTime?.();
+
+ +

使用空值合并操作符

+ +

{{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合并操作符")}}可以在使用可选链时设置一个默认值:

+ +
let customer = {
+  name: "Carl",
+  details: { age: 82 }
+};
+let customerCity = customer?.city ?? "暗之城";
+console.log(customerCity); // “暗之城”
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#prod-OptionalExpression', 'optional expression')}}Stage 4
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.operators.optional_chaining")}}

+ +

Implementation Progress

+ +

The following table provides a daily implementation status for this feature because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in Test262, the standard test suite of JavaScript, in the nightly build, or the latest release of each browser's JavaScript engine.

+ +

{{EmbedTest262ReportResultsTable("optional-chaining")}}

+
+ +

参见

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" "b/files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" new file mode 100644 index 0000000000..20eece2691 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" @@ -0,0 +1,106 @@ +--- +title: 按位与 (&) +slug: Web/JavaScript/Reference/Operators/按位与 +translation_of: Web/JavaScript/Reference/Operators/Bitwise_AND +--- +
{{jsSidebar("Operators")}}
+ +

按位与运算符 (&) 在每个位上返回 1 ,这两个操作数对应的位都是 1.

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-and.html")}}
+ + + +

语法

+ +
a & b
+
+ +

描述

+ +

操作数被转换为32位整数,并由一系列位(0和1)表示。 超过32位的数字将丢弃其最高有效位。 例如,以下大于32位的整数将被转换为32位整数:

+ +
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+ +

第一个操作数中的每个位都与第二个操作数中的相应位配对:第一位到第一位,第二位到第二位,依此类推。

+ +

将运算符应用于每对位,然后按位构造结果。

+ +

与运算的真值表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba AND b
000
010
100
111
+ +
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
+
+ +

将任何数字x0进行按位与运算将得出0

+ +

示例

+ +

使用按位与

+ +
// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+5 & 2; // 0
+ +

规范说明

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-BitwiseANDExpression', 'Bitwise AND expression')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_and")}}

+ +

参阅

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" new file mode 100644 index 0000000000..6da432b4e6 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" @@ -0,0 +1,79 @@ +--- +title: 相加运算符 (+) +slug: Web/JavaScript/Reference/Operators/相加 +translation_of: Web/JavaScript/Reference/Operators/Addition +--- +
{{jsSidebar("相加运算符")}}
+ +

相加运算符 (+) 用于对两个操作数进行相加运算,如果操作数为字符串则该运算符将两个操作数连接成一个字符串。

+ +
{{EmbedInteractiveExample("pages/js/expressions-addition.html")}}
+ +
+ + + +

语法

+ +
表达式: x + y
+
+ +

示例

+ +

数字的相加运算

+ +
// Number + Number -> addition
+1 + 2 // 3
+
+// Boolean + Number -> addition
+true + 1 // 2
+
+// Boolean + Boolean -> addition
+false + false // 0
+
+ +

字符串相加运算

+ +
// String + String -> concatenation
+'foo' + 'bar' // "foobar"
+
+// Number + String -> concatenation
+5 + 'foo' // "5foo"
+
+// String + Boolean -> concatenation
+'foo' + false // "foofalse"
+ +

注: '+'两侧只要有一侧是字符串,另一侧的数字则会自动转换成字符串,因为其中存在隐式转换

+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-addition-operator-plus', 'Addition operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.addition")}}

+ +

参考

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" new file mode 100644 index 0000000000..e100ec1d2d --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" @@ -0,0 +1,125 @@ +--- +title: 相等(==) +slug: Web/JavaScript/Reference/Operators/相等 +tags: + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Operators/Equality +--- +
{{jsSidebar("Operators")}}
+ +

等于运算符(==)检查其两个操作数是否相等,并返回Boolean结果。与严格相等运算符(===)不同,它会尝试强制类型转换并且比较不同类型的操作数。

+ +
{{EmbedInteractiveExample("pages/js/expressions-equality.html")}}
+ +

语法

+ +
x == y
+
+ +

描述

+ +

相等运算符(==!=)使用抽象相等比较算法比较两个操作数。可以大致概括如下:

+ + + +

此运算符与严格等于===)运算符之间最显着的区别在于,严格等于运算符不尝试类型转换。相反,严格相等运算符始终将不同类型的操作数视为不同。

+ +

例子

+ +

没有类型转换的比较

+ +
1 == 1;              // true
+"hello" == "hello";  // true
+ +

与类型转换比较

+ +
"1" ==  1;            // true
+1 == "1";             // true
+0 == false;           // true
+0 == null;            // false
+0 == undefined;       // false
+null == undefined;    // true
+
+const number1 = new Number(3);
+const number2 = new Number(3);
+number1 == 3;         // true
+number1 == number2;   // false
+ +

对象比较

+ +
const object1 = {"key": "value"}
+const object2 = {"key": "value"};
+
+object1 == object2 // false
+object2 == object2 // true
+ +

比较字符串和String对象

+ +

请注意,使用构造的字符串new String()是对象。如果将其中之一与字符串文字进行比较,则该String对象将被转换为字符串文字并对其内容进行比较。但是,如果两个操作数都是String对象,则将它们作为对象进行比较,并且必须引用相同的对象才能进行比较:

+ +
const string1 = "hello";
+const string2 = String("hello");
+const string3 = new String("hello");
+const string4 = new String("hello");
+
+console.log(string1 == string2); // true
+console.log(string1 == string3); // true
+console.log(string2 == string3); // true
+console.log(string3 == string4); // false
+console.log(string4 == string4); // true
+ +

比较日期和字符串

+ +
const d = new Date('December 17, 1995 03:24:00');
+const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)"
+console.log(d == s);    //true
+ +

技术指标

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.operators.equality")}}

+ +

参见

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" "b/files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" new file mode 100644 index 0000000000..06ce40ad0b --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" @@ -0,0 +1,75 @@ +--- +title: 管道操作符 +slug: Web/JavaScript/Reference/Operators/管道操作符 +tags: + - Experimental + - JavaScript + - Operator + - 语法糖 + - 链式 + - 链式调用 +translation_of: Web/JavaScript/Reference/Operators/Pipeline_operator +--- +
{{jsSidebar("Operators")}} {{SeeCompatTable}}
+ +

试验性的管道操作符 |> (目前其标准化流程处于 stage 1 阶段)允许以一种易读的方式去对函数链式调用。本质上来说,管道操作符是单参数函数调用的语法糖,它允许你像这样执行一个调用:

+ +
let url = "%21" |> decodeURI;
+ +

使用传统语法写的话,等效的代码是这样的:

+ +
let url = decodeURI("%21");
+
+ +

语法

+ +
expression |> function
+ +

例子

+ +

函数链式调用

+ +

当链式调用多个函数时,使用管道操作符可以改善代码的可读性。

+ +
const double = (n) => n * 2;
+const increment = (n) => n + 1;
+
+// 没有用管道操作符
+double(increment(double(5))); // 22
+
+// 用上管道操作符之后
+5 |> double |> increment |> double; // 22
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
Pipeline operator draftStage 1Not part of the ECMAScript specification yet.
+ +

浏览器兼容性Edit

+ +
+ + +

{{Compat("javascript.operators.pipeline")}}

+
+ +

参见

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" "b/files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" new file mode 100644 index 0000000000..f405740df3 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" @@ -0,0 +1,85 @@ +--- +title: 自减 (--) +slug: Web/JavaScript/Reference/Operators/自减 +tags: + - JavaScript + - 自减 + - 语法特性 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Decrement +--- +
{{jsSidebar("Operators")}}
+ +

 自减运算符(--) 将它的操作数减一,然后返回操作数.

+ +
{{EmbedInteractiveExample("pages/js/expressions-decrement.html")}}
+ +
+ + + +


+ 语法

+ +
操作符: x-- or --x
+
+ +

语法细节

+ +

如果使用后缀式,即将操作符放在操作数的后面 (如,x--),运算会减一,然后返回减一之前的值。

+ +

如果使用前缀式,即将操作符放在操作数的前面 (如,--x),运算会减一,然后返回减一之后的值。

+ +

示例

+ +

后缀式

+ +
let x = 3;
+y = x--;
+
+// y = 3
+// x = 2
+
+ +

前缀式

+ +
let a = 2;
+b = --a;
+
+// a = 1
+// b = 1
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-postfix-decrement-operator', '自减运算符')}}
+ +


+ 浏览器兼容性

+ + + +

{{Compat("javascript.operators.decrement")}}

+ +

相关链接

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" "b/files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" new file mode 100644 index 0000000000..de38317f42 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" @@ -0,0 +1,137 @@ +--- +title: 逻辑与(&&) +slug: Web/JavaScript/Reference/Operators/逻辑和 +translation_of: Web/JavaScript/Reference/Operators/Logical_AND +--- +
{{jsSidebar("Operators")}}
+ +

The logical AND (&&) operator (logical conjunction) for a set of operands is true if and only if all of its operands are true. It is typically used with {{jsxref("Boolean")}} (logical) values. When it is, it returns a Boolean value. However, the && operator actually returns the value of one of the specified operands, so if this operator is used with non-Boolean values, it will return a non-Boolean value.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-and.html", "shorter")}}
+ + + +

Syntax

+ +
expr1 && expr2
+
+ +

Description

+ +

If expr1 can be converted to true, returns expr2; else, returns expr1.

+ +

If a value can be converted to true, the value is so-called {{Glossary("truthy")}}. If a value can be converted to false, the value is so-called {{Glossary("falsy")}}.

+ +

Examples of expressions that can be converted to false are:

+ + + +

Even though the && operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.

+ +

Short-circuit evaluation

+ +

The logical AND expression is evaluated left to right, it is tested for possible "short-circuit" evaluation using the following rule:

+ +

(some falsy expression) && expr is short-circuit evaluated to the falsy expression;

+ +

Short circuit means that the expr part above is not evaluated, hence any side effects of doing so do not take effect (e.g., if expr is a function call, the calling never takes place). This happens because the value of the operator is already determined after the evaluation of the first operand. See example:

+ +
function A(){ console.log('called A'); return false; }
+function B(){ console.log('called B'); return true; }
+
+console.log( A() && B() );
+// logs "called A" due to the function call,
+// then logs false (which is the resulting value of the operator)
+
+ +

Operator precedence

+ +

The following expressions might seem equivalent, but they are not, because the && operator is executed before the || operator (see operator precedence).

+ +
true || false && false      // returns true, because && is executed first
+(true || false) && false    // returns false, because operator precedence cannot apply
+ +

Examples

+ +

Using AND

+ +

The following code shows examples of the && (logical AND) operator.

+ +
a1 = true  && true       // t && t returns true
+a2 = true  && false      // t && f returns false
+a3 = false && true       // f && t returns false
+a4 = false && (3 == 4)   // f && f returns false
+a5 = 'Cat' && 'Dog'      // t && t returns "Dog"
+a6 = false && 'Cat'      // f && t returns false
+a7 = 'Cat' && false      // t && f returns false
+a8 = ''    && false      // f && f returns ""
+a9 = false && ''         // f && f returns false
+ +

Conversion rules for booleans

+ +

Converting AND to OR

+ +

The following operation involving booleans:

+ +
bCondition1 && bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 || !bCondition2)
+ +

Converting OR to AND

+ +

The following operation involving booleans:

+ +
bCondition1 || bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 && !bCondition2)
+ +

Removing nested parentheses

+ +

As logical expressions are evaluated left to right, it is always possible to remove parentheses from a complex expression following some rules.

+ +

The following composite operation involving booleans:

+ +
bCondition1 || (bCondition2 && bCondition3)
+ +

is always equal to:

+ +
bCondition1 || bCondition2 && bCondition3
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-LogicalANDExpression', 'Logical AND expression')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.logical_and")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/reserved_words/index.html b/files/zh-cn/web/javascript/reference/reserved_words/index.html new file mode 100644 index 0000000000..51d67f323e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/reserved_words/index.html @@ -0,0 +1,81 @@ +--- +title: Reserved Words +slug: Web/JavaScript/Reference/Reserved_words +translation_of: Web/JavaScript/Reference/Lexical_grammar#Keywords +--- +

 

+ +

以下这些是ECMAScript规范已经规定的关键字,不能用作变量、函数名、过程、和对象名:

+ + + +

以下是ECMAScript规定的保留字:

+ + + +

请注意,虽然ECMA-262还没有正式规定,但是在Mozilla中const,export和import已经被作为保留字对待。

+ +
cn:Core JavaScript 1.5 Reference:Reserved Words + +

 

+
+ +

{{ languages( { "en": "en/Core_JavaScript_1.5_Reference/Reserved_Words" } ) }}

diff --git a/files/zh-cn/web/javascript/reference/statements/async_function/index.html b/files/zh-cn/web/javascript/reference/statements/async_function/index.html new file mode 100644 index 0000000000..cb6f595ff9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/async_function/index.html @@ -0,0 +1,327 @@ +--- +title: async函数 +slug: Web/JavaScript/Reference/Statements/async_function +tags: + - JavaScript + - 函数 + - 声明 + - 异步函数 + - 语言特性 +translation_of: Web/JavaScript/Reference/Statements/async_function +--- +
{{jsSidebar("Statements")}}
+ +

async函数是使用async关键字声明的函数。 async函数是{{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}}构造函数的实例, 并且其中允许使用await关键字。asyncawait关键字让我们可以用一种更简洁的方式写出基于{{jsxref("Promise")}}的异步行为,而无需刻意地链式调用promise

+ +
+

async函数还可以被{{jsxref("Operators/async_function", "作为表达式", "", 1)}}来定义。

+
+ +
{{EmbedInteractiveExample("pages/js/statement-async.html", "taller")}}
+ + + +

语法

+ +
async function name([param[, param[, ... param]]]) {
+    statements 
+}
+
+ +

参数

+ +
+
name
+
函数名称。
+
+ +
+
param
+
要传递给函数的参数的名称。
+
+ +
+
statements
+
包含函数主体的表达式。可以使用await机制。
+
+

返回值

+
+
一个{{jsxref("Promise")}},这个promise要么会通过一个由async函数返回的值被解决,要么会通过一个从async函数中抛出的(或其中没有被捕获到的)异常被拒绝。
+
+ +

描述

+ +

async函数可能包含0个或者多个{{jsxref("Operators/await", "await")}}表达式。await表达式会暂停整个async函数的执行进程并出让其控制权,只有当其等待的基于promise的异步操作被兑现或被拒绝之后才会恢复进程。promise的解决值会被当作该await表达式的返回值。使用async / await关键字就可以在异步代码中使用普通的try / catch代码块。

+ +
+

await关键字只在async函数内有效。如果你在async函数体之外使用它,就会抛出语法错误 {{jsxref("SyntaxError")}} 。

+
+ +
+

async/await的目的为了简化使用基于promise的API时所需的语法。async/await的行为就好像搭配使用了生成器和promise。

+
+ +

async函数一定会返回一个promise对象。如果一个async函数的返回值看起来不是promise,那么它将会被隐式地包装在一个promise中。

+ +

例如,如下代码:

+ +
async function foo() {
+   return 1
+}
+
+ +

等价于:

+ +
function foo() {
+   return Promise.resolve(1)
+}
+
+ +

async函数的函数体可以被看作是由0个或者多个await表达式分割开来的。从第一行代码直到(并包括)第一个await表达式(如果有的话)都是同步运行的。这样的话,一个不含await表达式的async函数是会同步运行的。然而,如果函数体内有一个await表达式,async函数就一定会异步执行。

+ +

例如:

+ +
async function foo() {
+   await 1
+}
+
+ +

等价于

+ +
function foo() {
+   return Promise.resolve(1).then(() => undefined)
+}
+
+ +

在await表达式之后的代码可以被认为是存在在链式调用的then回调中,多个await表达式都将加入链式调用的then回调中,返回值将作为最后一个then回调的返回值。

+ +

在接下来的例子中,我们将使用await执行两次promise,整个foo函数的执行将会被分为三个阶段。

+ +
    +
  1. foo函数的第一行将会同步执行,await将会等待promise的结束。然后暂停通过foo的进程,并将控制权交还给调用foo的函数。
  2. +
  3. 一段时间后,当第一个promise完结的时候,控制权将重新回到foo函数内。示例中将会将1(promise状态为fulfilled)作为结果返回给await表达式的左边即result1。接下来函数会继续进行,到达第二个await区域,此时foo函数的进程将再次被暂停。
  4. +
  5. 一段时间后,同样当第二个promise完结的时候,result2将被赋值为2,之后函数将会正常同步执行,将默认返回undefined 。
  6. +
+ +
async function foo() {
+   const result1 = await new Promise((resolve) => setTimeout(() => resolve('1')))
+   const result2 = await new Promise((resolve) => setTimeout(() => resolve('2')))
+}
+foo()
+ +

注意:promise链不是一次就构建好的,相反,promise链是分阶段构造的,因此在处理异步函数时必须注意对错误函数的处理。

+ +

例如,在下面的代码中,在promise链上配置了.catch处理程序,将抛出未处理的promise错误。这是因为p2返回的结果不会被await处理。

+ +
async function foo() {
+   const p1 = new Promise((resolve) => setTimeout(() => resolve('1'), 1000))
+   const p2 = new Promise((_,reject) => setTimeout(() => reject('2'), 500))
+   const results = [await p1, await p2] // 不推荐使用这种方式,请使用 Promise.all或者Promise.allSettled 
+}
+foo().catch(() => {}) // 捕捉所有的错误...
+ + + +

示例

+ +

简单例子

+ +
var resolveAfter2Seconds = function() {
+  console.log("starting slow promise");
+  return new Promise(resolve => {
+    setTimeout(function() {
+      resolve("slow");
+      console.log("slow promise is done");
+    }, 2000);
+  });
+};
+
+var resolveAfter1Second = function() {
+  console.log("starting fast promise");
+  return new Promise(resolve => {
+    setTimeout(function() {
+      resolve("fast");
+      console.log("fast promise is done");
+    }, 1000);
+  });
+};
+
+var sequentialStart = async function() {
+  console.log('==SEQUENTIAL START==');
+
+  // 1. Execution gets here almost instantly
+  const slow = await resolveAfter2Seconds();
+  console.log(slow); // 2. this runs 2 seconds after 1.
+
+  const fast = await resolveAfter1Second();
+  console.log(fast); // 3. this runs 3 seconds after 1.
+}
+
+var concurrentStart = async function() {
+  console.log('==CONCURRENT START with await==');
+  const slow = resolveAfter2Seconds(); // starts timer immediately
+  const fast = resolveAfter1Second(); // starts timer immediately
+
+  // 1. Execution gets here almost instantly
+  console.log(await slow); // 2. this runs 2 seconds after 1.
+  console.log(await fast); // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved
+}
+
+var concurrentPromise = function() {
+  console.log('==CONCURRENT START with Promise.all==');
+  return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
+    console.log(messages[0]); // slow
+    console.log(messages[1]); // fast
+  });
+}
+
+var parallel = async function() {
+  console.log('==PARALLEL with await Promise.all==');
+
+  // Start 2 "jobs" in parallel and wait for both of them to complete
+  await Promise.all([
+      (async()=>console.log(await resolveAfter2Seconds()))(),
+      (async()=>console.log(await resolveAfter1Second()))()
+  ]);
+}
+
+// This function does not handle errors. See warning below!
+var parallelPromise = function() {
+  console.log('==PARALLEL with Promise.then==');
+  resolveAfter2Seconds().then((message)=>console.log(message));
+  resolveAfter1Second().then((message)=>console.log(message));
+}
+
+sequentialStart(); // after 2 seconds, logs "slow", then after 1 more second, "fast"
+
+// wait above to finish
+setTimeout(concurrentStart, 4000); // after 2 seconds, logs "slow" and then "fast"
+
+// wait again
+setTimeout(concurrentPromise, 7000); // same as concurrentStart
+
+// wait again
+setTimeout(parallel, 10000); // truly parallel: after 1 second, logs "fast", then after 1 more second, "slow"
+
+// wait again
+setTimeout(parallelPromise, 13000); // same as parallel
+
+ +
+

await and parallelism(并行)

+ +

sequentialStart中,程序在第一个await停留了2秒,然后又在第二个await停留了1秒。直到第一个计时器结束后,第二个计时器才被创建。程序需要3秒执行完毕。

+ +


+ 在 concurrentStart中,两个计时器被同时创建,然后执行await。这两个计时器同时运行,这意味着程序完成运行只需要2秒,而不是3秒,即最慢的计时器的时间。

+ +

但是 await 仍旧是顺序执行的,第二个 await 还是得等待第一个执行完。在这个例子中,这使得先运行结束的输出出现在最慢的输出之后。

+ +

如果你希望并行执行两个或更多的任务,你必须像在parallel中一样使用await Promise.all([job1(), job2()])

+
+ +
+

async/await和Promise#then对比以及错误处理

+ +

大多数async函数也可以使用Promises编写。但是,在错误处理方面,async函数更容易捕获异常错误

+ +

上面例子中的concurrentStart函数和concurrentPromise函数在功能上都是等效的。在concurrentStart函数中,如果任一awaited调用失败,它将自动捕获异常,async函数执行中断,并通过隐式返回Promise将错误传递给调用者。

+ +

在Promise例子中这种情况同样会发生,该函数必须负责返回一个捕获函数完成的Promise。在concurrentPromise函数中,这意味着它从Promise.all([]).then()返回一个Promise。事实上,在此示例的先前版本忘记了这样做!

+ +

但是,async函数仍有可能然可能错误地忽略错误。
+ 以parallel async函数为例。 如果它没有等待await(或返回)Promise.all([])调用的结果,则不会传播任何错误。
+ 虽然parallelPromise函数示例看起来很简单,但它根本不会处理错误! 这样做需要一个类似于return Promise.all([])处理方式。

+
+ +

使用async函数重写 promise 链

+ +

返回 {{jsxref("Promise")}}的 API 将会产生一个 promise 链,它将函数肢解成许多部分。例如下面的代码:

+ +
function getProcessedData(url) {
+  return downloadData(url) // 返回一个 promise 对象
+    .catch(e => {
+      return downloadFallbackData(url)  // 返回一个 promise 对象
+    })
+    .then(v => {
+      return processDataInWorker(v); // 返回一个 promise 对象
+    });
+}
+ +

可以重写为单个async函数:

+ +
async function getProcessedData(url) {
+  let v;
+  try {
+    v = await downloadData(url);
+  } catch (e) {
+    v = await downloadFallbackData(url);
+  }
+  return processDataInWorker(v);
+}
+
+ +

注意,在上述示例中,return 语句中没有 await 操作符,因为 async function 的返回值将被隐式地传递给 {{jsxref("Promise.resolve")}}

+ +
+

return await promiseValue; 与 return promiseValue;的比较

+ +

返回值隐式的传递给{{jsxref("Promise.resolve")}},并不意味着return await promiseValue;和return promiseValue;在功能上相同。

+ +

看下下面重写的上面代码,在processDataInWorker抛出异常时返回了null:

+ +
async function getProcessedData(url) {
+  let v;
+  try {
+    v = await downloadData(url);
+  } catch(e) {
+    v = await downloadFallbackData(url);
+  }
+  try {
+    return await processDataInWorker(v); // 注意 `return await` 和单独 `return` 的比较
+  } catch (e) {
+    return null;
+  }
+}
+ +

简单地写上return processDataInworker(v);将导致在processDataInWorker(v)出错时function返回值为{{jsxref("Promise")}}而不是返回null。return foo;return await foo;,有一些细微的差异:return foo;不管foo是promise还是rejects都将会直接返回foo。相反地,如果foo是一个{{jsxref("Promise")}},return await foo;将等待foo执行(resolve)或拒绝(reject),如果是拒绝,将会在返回前抛出异常。

+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}{{Spec2('ESDraft')}}初始定义于ES2017.
{{SpecName('ES8', '#sec-async-function-definitions', 'async function')}}{{Spec2('ES8')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.async_function")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/block/index.html b/files/zh-cn/web/javascript/reference/statements/block/index.html new file mode 100644 index 0000000000..4188e5a2ec --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/block/index.html @@ -0,0 +1,163 @@ +--- +title: block +slug: Web/JavaScript/Reference/Statements/block +tags: + - JavaScript + - Reference + - Statement +translation_of: Web/JavaScript/Reference/Statements/block +--- +
+
{{jsSidebar("Statements")}}
+
+ +

块语句(或其他语言的复合语句)用于组合零个或多个语句。该块由一对大括号界定,可以是{{jsxref("Statements/label", "labelled")}}:

+ +

语法

+ +

块声明

+ +
{ StatementList }
+
+ +

标记块声明

+ +
LabelIdentifier: { StatementList }
+
+ +
+
StatementList
+
在块语句中分组的语句。
+
LabelIdentifier
+
用于视觉识别的可选{{jsxref("Statements/label", "label")}}或{{jsxref("Statements/break", "break")}}的目标。
+
+ +

描述

+ +

其他语言中通常将语句块称为复合语句。它允许你使用多个语句,其中 JavaScript 只需要一个语句。将语句组合成块是 JavaScript 中的常见做法。相反的做法是可以使用一个空语句,你不提供任何语句,虽然一个是必需的。

+ +

块级作用域

+ +

在非严格模式(non-strict mode)下的var 或者函数声明时

+ +

通过var声明的变量或者非严格模式下(non-strict mode)创建的函数声明没有块级作用域。在语句块里声明的变量的作用域不仅是其所在的函数或者 script 标签内,所设置变量的影响会在超出语句块本身之外持续存在。 换句话说,这种语句块不会引入一个作用域。尽管单独的语句块是合法的语句,但在JavaScript中你不会想使用单独的语句块,因为它们不像你想象的C或Java中的语句块那样处理事物。例如:

+ +
var x = 1;
+{
+  var x = 2;
+}
+console.log(x); // 输出 2
+
+ +

输出结果是 2,因为块中的 var x语句与块前面的var x语句作用域相同。在 C 或 Java中,这段代码会输出 1。

+ + + +

使用letconst

+ +

相比之下,使用 {{jsxref("Statements/let", "let")}}和{{jsxref("Statements/const", "const")}}声明的变量是块级作用域的。

+ +
let x = 1;
+{
+  let x = 2;
+}
+console.log(x); // 输出 1
+ +

x = 2仅限在定义它的块中。

+ +

const的结果也是一样的:

+ +
const c = 1;
+{
+  const c = 2;
+}
+console.log(c); // 输出1, 而且不会报错
+ +

注意,位于块范围之内的 const c = 2 并不会抛出SyntaxError: Identifier 'c' has already been declared这样的语法错误,因为在它自己的块中它可能是唯一一个被声明的常量。

+ +
使用let声明的变量在块级作用域内能强制执行更新变量,下面的两个例子对比:
+ +
var a = [];
+for (var i = 0; i < 10; i++) {
+      a[i] = function () {console.log(i);};
+}
+a[0]();                // 10
+a[1]();                // 10
+a[6]();                // 10
+
+/********************/
+
+var a = [];
+for (let i = 0; i < 10; i++) {
+      a[i] = function () {console.log(i);};
+}
+a[0]();                // 0
+a[1]();                // 1
+a[6]();                // 6
+ +

使用function

+ +

函数声明同样被限制在声明他的语句块内:

+ + + +
foo('outside');  // TypeError: foo is not a function
+{
+  function foo(location) {
+   console.log('foo is called ' + location);
+  }
+  foo('inside'); // 正常工作并且打印 'foo is called inside'
+}
+ + + +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-block', 'Block statement')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-block', 'Block statement')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-12.1', 'Block statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-12.1', 'Block statement')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-12.1', 'Block statement')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.block")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/break/index.html b/files/zh-cn/web/javascript/reference/statements/break/index.html new file mode 100644 index 0000000000..9cecd6eef9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/break/index.html @@ -0,0 +1,175 @@ +--- +title: break +slug: Web/JavaScript/Reference/Statements/break +tags: + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/break +--- +
+
{{jsSidebar("Statements")}}
+
+ +

break 语句中止当前循环,{{jsxref("Statements/switch", "switch")}}语句或{{jsxref("Statements/label", "label")}} 语句,并把程序控制流转到紧接着被中止语句后面的语句。

+ +

语法

+ +
break [label];
+ +
+
label {{可选}}
+
与语句标签相关联的标识符。如果 break 语句不在一个循环或 {{jsxref("Statements/switch", "switch")}} 语句中,则该项是必须的。
+
+ +

描述

+ +

break语句包含一个可选的标签,可允许程序摆脱一个被标记的语句。break语句需要内嵌在引用的标签中。被标记的语句可以是任何 {{jsxref("Statements/block", "块")}}语句;不一定是循环语句。

+ +

break语句不能在function函数体中直接使用,break语句应嵌套在要中断的当前循环、switch或label语句中。

+ +

示例

+ +

break in while loop

+ +

下面的函数里有个 break 语句,当 i 为 3 时,会中止 {{jsxref("Statements/while", "while")}} 循环,然后返回 3 * x 的值。

+ +
function testBreak(x) {
+  var i = 0;
+
+  while (i < 6) {
+    if (i == 3) {
+      break;
+    }
+    i += 1;
+  }
+
+  return i * x;
+}
+ +

break in switch statements

+ +

在下面的代码中, break 使用在 {{jsxref("Statements/switch", "switch")}} 语句中,当遇到匹配到case后,就会执行相应的代码并中断循环体。

+ +
const food = "sushi";
+
+switch (food) {
+  case "sushi":
+    console.log("Sushi is originally from Japan.");
+    break;
+  case "pizza":
+    console.log("Pizza is originally from Italy.");
+    break;
+  default:
+    console.log("I have never heard of that dish.");
+    break;
+}
+ +

break in labeled blocks

+ +

下面的代码中一起使用 break 语句和被标记的块语句。一个 break 语句必须内嵌在它引用的标记中。注意,inner_block 内嵌在 outer_block 中。

+ +
outer_block:{
+
+  inner_block:{
+    console.log ('1');
+    break outer_block;      // breaks out of both inner_block and outer_block
+    console.log (':-(');    // skipped
+  }
+
+  console.log ('2');        // skipped
+}
+
+ +

break in labeled blocks that throw

+ +

下面的代码同样使用了 break 语句和被标记的块语句,但是产生了一个语法错误,因为它的 break 语句在 block_1 中,但是引用了 block_2break 语句必须内嵌在它引用的标签中。

+ +
block_1:{
+  console.log ('1');
+  break block_2;            // SyntaxError: label not found
+}
+
+block_2:{
+  console.log ('2');
+}
+
+ +

break within functions

+ +

在下面的代码同样会产生SyntaxError,因为它并没被正确的使用在循环、switch或label语句中。

+ +
function testBreak(x) {
+  var i = 0;
+
+  while (i < 6) {
+    if (i == 3) {
+      (function() {
+        break;
+      })();
+    }
+    i += 1;
+  }
+
+return i * x;
+}
+
+testBreak(1); // SyntaxError: Illegal break statement
+
+ +
block_1: {
+  console.log('1');
+  ( function() {
+    break block_1; // SyntaxError: Undefined label 'block_1'
+  })();
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Unlabeled version.
{{SpecName('ES3')}}{{Spec2('ES3')}}Labeled version added.
{{SpecName('ES5.1', '#sec-12.8', 'Break statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-break-statement', 'Break statement')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-break-statement', 'Break statement')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.break")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/class/index.html b/files/zh-cn/web/javascript/reference/statements/class/index.html new file mode 100644 index 0000000000..a5206d5b9c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/class/index.html @@ -0,0 +1,119 @@ +--- +title: class +slug: Web/JavaScript/Reference/Statements/class +tags: + - Class + - Classes + - Declaration + - ECMAScript 2015 + - ES6 + - JavaScript + - Reference + - Statement +translation_of: Web/JavaScript/Reference/Statements/class +--- +
{{jsSidebar("Statements")}}
+ +

class 声明创建一个基于原型继承的具有给定名称的新类。

+ +

{{EmbedInteractiveExample("pages/js/statement-class.html")}}

+ +
+

你也可以使用{{jsxref("Operators/class", "类表达式", "", 1)}}定义类。但是不同于类表达式,类声明不允许再次声明已经存在的类,否则将会抛出一个类型错误。

+
+ +

语法

+ +
class name [extends] {
+  // class body
+}
+
+ +

描述

+ +

和类表达式一样,类声明体在严格模式下运行。构造函数是可选的。

+ +

类声明不可以提升(这与函数声明不同)。

+ +

示例

+ +

声明一个类

+ +

在下面的例子中,我们首先定义一个名为Polygon的类,然后继承它来创建一个名为Square的类。注意,构造函数中使用的 super() 只能在构造函数中使用,并且必须在使用 this 关键字前调用。

+ +
class Polygon {
+  constructor(height, width) {
+    this.name = 'Polygon';
+    this.height = height;
+    this.width = width;
+  }
+}
+
+class Square extends Polygon {
+  constructor(length) {
+    super(length, length);
+    this.name = 'Square';
+  }
+}
+ +
+

重复定义类

+ +

重复声明一个类会引起类型错误。

+ +
class Foo {};
+class Foo {};
+// Uncaught TypeError: Identifier 'Foo' has already been declared
+ +

若之前使用类表达式定义了一个类,则再次声明这个类同样会引起类型错误。

+ +
let Foo = class {};
+class Foo {};
+// Uncaught TypeError: Identifier 'Foo' has already been declared
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ES2016', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2016')}} 
{{SpecName('ES2017', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2017')}} 
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.class")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/const/index.html b/files/zh-cn/web/javascript/reference/statements/const/index.html new file mode 100644 index 0000000000..75a1676299 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/const/index.html @@ -0,0 +1,152 @@ +--- +title: const +slug: Web/JavaScript/Reference/Statements/const +tags: + - ECMAScript 2015 + - JavaScript + - Reference + - Statement + - constants +translation_of: Web/JavaScript/Reference/Statements/const +--- +
{{jsSidebar("Statements")}}
+ +

常量是块级范围的,非常类似用 let 语句定义的变量。但常量的值是无法(通过重新赋值)改变的,也不能被重新声明。

+ +
{{EmbedInteractiveExample("pages/js/statement-const.html")}}
+ + + +

语法

+ +
const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]];
+ +
+
nameN
+
常量名称,可以是任意合法的{{Glossary("identifier","标识符")}}。
+
valueN
+
常量值,可以是任意合法的表达式
+
+ +

描述

+ +

此声明创建一个常量,其作用域可以是全局或本地声明的块。 与var变量不同,全局常量不会变为 window 对象的属性。需要一个常数的初始化器;也就是说,您必须在声明的同一语句中指定它的值(这是有道理的,因为以后不能更改)。

+ +

const声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。例如,在引用内容是对象的情况下,这意味着可以改变对象的内容(例如,其参数)。

+ +

关于“暂存死区”的所有讨论都适用于letconst

+ +

一个常量不能和它所在作用域内的其他变量或函数拥有相同的名称。

+ +

示例

+ +

const 基本用法

+ +

常量在声明的时候可以使用大小写,但通常情况下全部用大写字母。

+ +
// 定义常量MY_FAV并赋值7
+const MY_FAV = 7;
+
+// 报错 - Uncaught TypeError: Assignment to constant variable.
+MY_FAV = 20;
+
+// MY_FAV is 7
+console.log('my favorite number is: ' + MY_FAV);
+
+// 尝试重新声明会报错
+// Uncaught SyntaxError: Identifier 'MY_FAV' has already been declared
+const MY_FAV = 20;
+
+// MY_FAV 保留给上面的常量,这个操作会失败
+var MY_FAV = 20;
+
+// 也会报错
+let MY_FAV = 20;
+
+
+ +

块作用域

+ +

注意块作用域的性质很重要

+ +
if (MY_FAV === 7) {
+  // 没问题,并且创建了一个块作用域变量 MY_FAV
+  // (works equally well with let to declare a block scoped non const variable)
+  let MY_FAV = 20;
+
+  // MY_FAV 现在为 20
+  console.log('my favorite number is ' + MY_FAV);
+
+  // 这被提升到全局上下文并引发错误
+  var MY_FAV = 20;
+}
+
+// MY_FAV 依旧为7
+console.log('my favorite number is ' + MY_FAV);
+
+ +

常量要求一个初始值

+ +
// 报错
+// Uncaught SyntaxError: Missing initializer in const declaration
+
+const FOO;
+
+ +

常量可以定义成对象和数组

+ +

常量可以定义成对象和数组

+ +
const MY_OBJECT = {'key': 'value'};
+
+// 重写对象和上面一样会失败
+// Uncaught TypeError: Assignment to constant variable.
+MY_OBJECT = {'OTHER_KEY': 'value'};
+
+// 对象属性并不在保护的范围内
+// 下面这个声明会成功执行
+MY_OBJECT.key = 'otherValue'; // Use Object.freeze() to make object immutable
+
+// 也可以用来定义数组
+const MY_ARRAY = [];
+// 可以向数组填充数据
+MY_ARRAY.push('A'); // ["A"]
+// 但是,将一个新数组赋给变量会引发错误
+// Uncaught TypeError: Assignment to constant variable.
+MY_ARRAY = ['B'];
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-let-and-const-declarations', 'Let and Const Declarations')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-let-and-const-declarations', 'Let and Const Declarations')}}{{Spec2('ESDraft')}}No changes.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.const")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/continue/index.html b/files/zh-cn/web/javascript/reference/statements/continue/index.html new file mode 100644 index 0000000000..dfea4a3be3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/continue/index.html @@ -0,0 +1,156 @@ +--- +title: continue +slug: Web/JavaScript/Reference/Statements/continue +translation_of: Web/JavaScript/Reference/Statements/continue +--- +
+
{{jsSidebar("Statements")}}
+
+ +

continue 声明终止当前循环或标记循环的当前迭代中的语句执行,并在下一次迭代时继续执行循环。

+ +

{{EmbedInteractiveExample("pages/js/statement-continue.html")}}

+ +

语法

+ +
continue [ label ];
+ +
+
+ +
+
label
+
标识标号关联的语句
+
+ +

描述

+ +

与 {{jsxref("Statements/break", "break")}} 语句的区别在于, continue 并不会终止循环的迭代,而是:

+ + + + + +

continue 语句可以包含一个可选的标号以控制程序跳转到指定循环的下一次迭代,而非当前循环。此时要求 continue 语句在对应的循环内部。

+ +

示例

+ +

while 语句中使用 continue

+ +

下述例子展示了一个在i 为 3时执行continue 语句的 {{jsxref("Statements/while", "while")}} 循环。因此,n 的值在几次迭代后分别为 1, 3, 7 和 12 .

+ +
i = 0;
+n = 0;
+while (i < 5) {
+   i++;
+   if (i === 3) {
+      continue;
+   }
+   n += i;
+}
+ +

使用带 label 的 continue

+ +

在下面的例子中,被标记为 checkiandj 的语句包含一个被标记为 checkj 的语句。当遇到continue 语句时,程序回到 checkj 语句的开始继续执行。每次遇到 continue 时,再次执行 checkj ,直到条件判断返回 false 。之后完成 checkiandj 语句剩下的部分。

+ +

但如果 continue 的标号被改为 checkiandj ,那程序将会从 checkiandj 语句的开始继续运行。

+ +

参考 {{jsxref("Statements/label", "label")}} 。

+ +
var i = 0,
+    j = 8;
+
+checkiandj: while (i < 4) {
+   console.log("i: " + i);
+   i += 1;
+
+   checkj: while (j > 4) {
+      console.log("j: "+ j);
+      j -= 1;
+      if ((j % 2) == 0)
+         continue checkj;
+      console.log(j + " is odd.");
+   }
+   console.log("i = " + i);
+   console.log("j = " + j);
+}
+ +

输出:

+ +
"i: 0"
+
+// start checkj
+"j: 8"
+"7 is odd."
+"j: 7"
+"j: 6"
+"5 is odd."
+"j: 5"
+// end checkj
+
+"i = 1"
+"j = 4"
+
+"i: 1"
+"i = 2"
+"j = 4"
+
+"i: 2"
+"i = 3"
+"j = 4"
+
+"i: 3"
+"i = 4"
+"j = 4"
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Unlabeled version.
{{SpecName('ES3')}}{{Spec2('ES3')}}Labeled version added.
{{SpecName('ES5.1', '#sec-12.7', 'Continue statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-continue-statement', 'Continue statement')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-continue-statement', 'Continue statement')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.statements.continue")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/debugger/index.html b/files/zh-cn/web/javascript/reference/statements/debugger/index.html new file mode 100644 index 0000000000..664e35af1e --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/debugger/index.html @@ -0,0 +1,79 @@ +--- +title: debugger +slug: Web/JavaScript/Reference/Statements/debugger +tags: + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/debugger +--- +

{{jsSidebar("Statements")}}

+ +

debugger 语句调用任何可用的调试功能,例如设置断点。 如果没有调试功能可用,则此语句不起作用。

+ +

语法

+ +
debugger;
+
+ +

示例

+ +

下面的例子演示了一个包含 debugger 语句的函数,当函数被调用时,会尝试调用一个可用的调试器进行调试。

+ +
function potentiallyBuggyCode() {
+    debugger;
+    // do potentially buggy stuff to examine, step through, etc.
+}
+ +

当 debugger 被调用时, 执行暂停在 debugger 语句的位置。就像在脚本源代码中的断点一样。

+ +

Paused at a debugger statement.

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-debugger-statement', 'Debugger statement')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-debugger-statement', 'Debugger statement')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-12.15', 'Debugger statement')}}{{Spec2('ES5.1')}}Initial definition
{{SpecName('ES3', '#sec-7.5.3', 'Debugger statement')}}{{Spec2('ES3')}} 
{{SpecName('ES1', '#sec-7.4.3', 'Debugger statement')}}{{Spec2('ES1')}}Only mentioned as reserved word.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.debugger")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/default/index.html b/files/zh-cn/web/javascript/reference/statements/default/index.html new file mode 100644 index 0000000000..914eed34fd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/default/index.html @@ -0,0 +1,119 @@ +--- +title: default +slug: Web/JavaScript/Reference/Statements/default +tags: + - JavaScript + - Keyword +translation_of: Web/JavaScript/Reference/Statements/switch +--- +
{{jsSidebar("Statements")}}
+ +
+ +

default 关键字可以在 JavaScript 的两种情况下使用:在 {{jsxref("Statements/switch", "switch")}} ,或 {{jsxref("Statements/export", "export")}} 中。

+ +

语法

+ +

在{{jsxref("Statements/switch", "switch")}} 语句中使用:

+ +
switch (expression) {
+  case value1:
+    //当表达式的值和value1匹配执行这里的语句
+    [break;]
+  default:
+    //当表达式的值没有匹配,执行这里的语句
+    [break;]
+}
+ +

在{{jsxref("Statements/export", "export")}} 中使用:

+ +
export default nameN 
+ +

描述

+ +

更多细节,参见

+ + + +

示例

+ +

switch语句中使用default

+ +

在以下示例中,如果expr为“Oranges”或“Apples”,程序将匹配“Oranges”或“Apples”的值并执行相应的声明。在任何其它情况下,default关键字将执行关联的语句。

+ +
switch (expr) {
+  case "Oranges":
+    console.log("Oranges are $0.59 a pound.");
+    break;
+  case "Apples":
+    console.log("Apples are $0.32 a pound.");
+    break;
+  default:
+    console.log("Sorry, we are out of " + expr + ".");
+}
+ +

export语句中使用default

+ +

如果要导出单个值或需要模块的回调值,则可以使用默认导出: 

+ +
// module "my-module.js"
+let cube = function cube(x) {
+  return x * x * x;
+}
+export default cube;
+
+ +

然后,在另一个脚本中,默认导出将直接被导入:

+ +
// module "my-module.js"
+import myFunction from 'my-module';
+console.log(myFunction(3)); // 27
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-switch-statement', 'switch statement')}}{{Spec2('ES6')}}
{{SpecName('ES6', '#sec-exports', 'Exports')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-switch-statement', 'switch statement')}}{{Spec2('ESDraft')}}
{{SpecName('ESDraft', '#sec-exports', 'Exports')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.default")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/do...while/index.html b/files/zh-cn/web/javascript/reference/statements/do...while/index.html new file mode 100644 index 0000000000..bd3fb46473 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/do...while/index.html @@ -0,0 +1,99 @@ +--- +title: do...while +slug: Web/JavaScript/Reference/Statements/do...while +tags: + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/do...while +--- +
+
{{jsSidebar("Statements")}}
+
+ +

do...while 语句创建一个执行指定语句的循环,直到condition值为 false。在执行statement 后检测condition,所以指定的statement至少执行一次。

+ +

语法

+ +
do
+   statement
+while (condition);
+
+ +
+
statement
+
执行至少一次的语句,并在每次 condition 值为真时重新执行。想执行多行语句,可使用{{jsxref("Statements/block", "block")}}语句{ ... }包裹这些语句。
+
+ +
+
condition
+
循环中每次都会计算的表达式。如果 condition 值为真, statement 会再次执行。当 condition 值为假,则跳到do...while之后的语句。
+
+ +

示例

+ +

使用 do...while

+ +

下面的例子中,do...while 循环至少迭代一次,并且继续迭代直到 i不再小于 5 时结束。

+ +

HTML 内容

+ +
<div id="example"></div>
+ +

JavaScript 内容

+ +
var result = '';
+var i = 0;
+do {
+   i += 1;
+   result += i + ' ';
+} while (i < 5);
+document.getElementById('example').innerHTML = result;
+ +

结果

+ +

{{ EmbedLiveSample('Examples') }}

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2
{{SpecName('ES5.1', '#sec-12.6.1', 'do-while statement')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-do-while-statement', 'do-while statement')}}{{Spec2('ES6')}}Trailing ; is now optional.
{{SpecName('ESDraft', '#sec-do-while-statement', 'do-while statement')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.do_while")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/empty/index.html b/files/zh-cn/web/javascript/reference/statements/empty/index.html new file mode 100644 index 0000000000..3a03a63165 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/empty/index.html @@ -0,0 +1,103 @@ +--- +title: empty +slug: Web/JavaScript/Reference/Statements/Empty +tags: + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/Empty +--- +
+
{{jsSidebar("Statements")}}
+
+ +

空语句用来表明没有语句,尽管 JavaScript 语法希望有语句。

+ +

语法

+ +
;
+
+ +

描述

+ +

空语句是一个分号(;),表示不会执行任何语句,即使 JavaScript 语法需要一个语句。 相反,当你需要多行语句,但 JavaScript 只允许一个时,可以使用语句块;语句块可以将多条语句合并为一个。

+ +

示例

+ +

语句有时与循环语句一起使用。以下示例使用空循环体:

+ +
var arr = [1, 2, 3];
+
+// Assign all array values to 0
+for (let i = 0; i < arr.length; arr[i++] = 0) /* empty statement */ ;
+
+console.log(arr)
+// [0, 0, 0]
+
+ +

提示:在使用空语句的情况下专门写上注释是个不错的主意,因为不是很容易区分空语句和普通的分号。下面的示例可能不是故意加上分号的:

+ +
if (condition);       // Caution, this "if" does nothing!
+   killTheUniverse()  // So this gets always executed!!!
+
+ +

另一个例子:if...else 语句不带花括号({})。如果threetrue, 不会发生任何事,four不会执行,同时else从句中的launchRocket()函数也不会执行。

+ +
if (one)
+  doOne();
+else if (two)
+  doTwo();
+else if (three)
+  ; // nothing here
+else if (four)
+  doFour();
+else
+  launchRocket();
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-empty-statement', 'Empty statement')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-empty-statement', 'Empty statement')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-12.3', 'Empty statement')}}{{Spec2('ES5.1')}} 
{{SpecName('ES3', '#sec-12.3', 'Empty statement')}}{{Spec2('ES3')}} 
{{SpecName('ES1', '#sec-12.3', 'Empty statement')}}{{Spec2('ES1')}}Initial definition.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.empty")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/export/index.html b/files/zh-cn/web/javascript/reference/statements/export/index.html new file mode 100644 index 0000000000..9e584a2903 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/export/index.html @@ -0,0 +1,268 @@ +--- +title: export +slug: Web/JavaScript/Reference/Statements/export +tags: + - ECMAScript 2015 + - JavaScript + - export + - 声明 + - 模块 +translation_of: Web/JavaScript/Reference/Statements/export +--- +
{{jsSidebar("Statements")}}
+ +

在创建JavaScript模块时,export 语句用于从模块中导出实时绑定的函数、对象或原始值,以便其他程序可以通过 {{jsxref("Statements/import", "import")}} 语句使用它们。被导出的绑定值依然可以在本地进行修改。在使用import进行导入时,这些绑定值只能被导入模块所读取,但在export导出模块中对这些绑定值进行修改,所修改的值也会实时地更新。

+ +

无论您是否声明,导出的模块都处于{{jsxref("Strict_mode","严格模式")}}。 export语句不能用在嵌入式脚本中。

+ +

语法

+ +

存在两种 exports 导出方式:

+ +
    +
  1. 命名导出(每个模块包含任意数量)
  2. +
  3. 默认导出(每个模块包含一个)
  4. +
+ +
// 导出单个特性
+export let name1, name2, …, nameN; // also var, const
+export let name1 = …, name2 = …, …, nameN; // also var, const
+export function FunctionName(){...}
+export class ClassName {...}
+
+// 导出列表
+export { name1, name2, …, nameN };
+
+// 重命名导出
+export { variable1 as name1, variable2 as name2, …, nameN };
+
+// 解构导出并重命名
+export const { name1, name2: bar } = o;
+
+// 默认导出
+export default expression;
+export default function (…) { … } // also class, function*
+export default function name1(…) { … } // also class, function*
+export { name1 as default, … };
+
+// 导出模块合集
+export * from …; // does not set the default export
+export * as name1 from …; // Draft ECMAScript® 2O21
+export { name1, name2, …, nameN } from …;
+export { import1 as name1, import2 as name2, …, nameN } from …;
+export { default } from …;
+ +
+
nameN
+
要导出的标识符(以便其他脚本通过 {{jsxref("Statements/import", "import")}} 语句进行导入).
+
+ +

描述

+ +

有两种不同的导出方式,命名导出和默认导出。你能够在每一个模块中定义多个命名导出,但是只允许有一个默认导出。每种方式对应于上述的一种语法:

+ +

命名导出:

+ +
// 导出事先定义的特性
+export { myFunction,myVariable };
+
+// 导出单个特性(可以导出var,let,
+//const,function,class)
+export let myVariable = Math.sqrt(2);
+export function myFunction() { ... };
+ +

默认导出:

+ +
// 导出事先定义的特性作为默认值
+export { myFunction as default };
+
+// 导出单个特性作为默认值
+export default function () { ... }
+export default class { .. }
+
+// 每个导出都覆盖前一个导出
+ +

在导出多个值时,命名导出非常有用。在导入期间,必须使用相应对象的相同名称。

+ +

但是,可以使用任何名称导入默认导出,例如:

+ +
// 文件 test.js
+let k; export default k = 12; 
+ +
// 另一个文件
+import m from './test'; // 由于 k 是默认导出,所以可以自由使用 import m 替代 import k
+console.log(m);        // 输出为 12 
+ +

 你也可以重命名命名导出以避免命名冲突:

+ +
export { myFunction as function1,
+         myVariable as variable };
+ +

重导出 / 聚合

+ +

为了使模块导入变得可用,在一个父模块中“导入/导出”这些不同模块也是可行的。也就是说,你可以创建单个模块,集中多个模块的多个导出。

+ +

这个可以使用“export from”语法实现:

+ +
export { default as function1,
+         function2 } from 'bar.js';
+
+ +

与之形成对比的是联合使用导入和导出:

+ +
import { default as function1,
+         function2 } from 'bar.js';
+export { function1, function2 };
+
+ +

但这里的 function1 和 function2 在当前模块中变得不可用。

+ +
+

注意:尽管与import等效,但以下语法在语法上无效:

+
+ +
import DefaultExport from 'bar.js'; // 有效的
+
+ +
export DefaultExport from 'bar.js'; // 无效的
+ +

这里正确的做法是重命名这个导出:

+ +
export { default as DefaultExport } from 'bar.js';
+ +

示例

+ +

使用命名导出

+ +

在模块 my-module.js 中,可能包含以下代码:

+ +
// module "my-module.js"
+function cube(x) {
+  return x * x * x;
+}
+
+const foo = Math.PI + Math.SQRT2;
+
+var graph = {
+    options: {
+        color:'white',
+        thickness:'2px'
+    },
+    draw: function() {
+        console.log('From graph draw function');
+    }
+}
+
+export { cube, foo, graph };
+
+ +

然后,在你的 HTML 页面的顶级模块中:

+ +
import { cube, foo, graph } from 'my-module.js';
+
+graph.options = {
+    color:'blue',
+    thickness:'3px'
+};
+
+graph.draw();
+console.log(cube(3)); // 27
+console.log(foo);    // 4.555806215962888
+ +

着重注意以下几点:

+ + + +

使用默认导出

+ +

如果我们要导出一个值或得到模块中的返回值,就可以使用默认导出:

+ +
// module "my-module.js"
+
+export default function cube(x) {
+  return x * x * x;
+}
+
+ +

然后,在另一个脚本中,可以直接导入默认导出:

+ +
import cube from './my-module.js';
+console.log(cube(3)); // 27​​​​​
+
+ +

模块重定向

+ +

举个例子,假如我们有如下层次结构:

+ + + +

你的代码看起来应该像这样:

+ +
// childModule1.js 中
+let myFunction = ...; // assign something useful to myFunction
+let myVariable = ...; // assign something useful to myVariable
+export {myFunction, myVariable};
+ +
// childModule2.js 中
+let myClass = ...; // assign something useful to myClass
+export myClass;
+
+ +
// parentModule.js 中
+// 仅仅聚合 childModule1 和 childModule2 中的导出
+// 以重新导出他们
+export { myFunction, myVariable } from 'childModule1.js';
+export { myClass } from 'childModule2.js';
+
+ +
// 顶层模块中
+// 我们可以从单个模块调用所有导出,因为 parentModule 事先
+// 已经将他们“收集”/“打包”到一起
+import { myFunction, myVariable, myClass } from 'parentModule.js'
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES2015', '#sec-exports', 'Exports')}}{{Spec2('ES2015')}}初版
{{SpecName('ESDraft', '#sec-exports', 'Exports')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.export")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/for-await...of/index.html b/files/zh-cn/web/javascript/reference/statements/for-await...of/index.html new file mode 100644 index 0000000000..87033e17ba --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/for-await...of/index.html @@ -0,0 +1,161 @@ +--- +title: for await...of +slug: Web/JavaScript/Reference/Statements/for-await...of +tags: + - JavaScript + - Reference + - Statement + - await + - for + - for await...of + - for...in + - for...of + - 异步 + - 迭代 +translation_of: Web/JavaScript/Reference/Statements/for-await...of +--- +

{{jsSidebar("Statements")}}

+ +

for await...of 语句创建一个循环,该循环遍历异步可迭代对象以及同步可迭代对象,包括: 内置的 {{jsxref("String")}}, {{jsxref("Array")}},类似数组对象 (例如 {{jsxref("Functions/arguments", "arguments")}}  {{DOMxRef("NodeList")}}){{jsxref("TypedArray")}}, {{jsxref("Map")}}, {{jsxref("Set")}} 和用户定义的异步/同步迭代器。它使用对象的每个不同属性的值调用要执行的语句来调用自定义迭代钩子。

+ +

类似于 {{jsxref("Operators/await", "await")}} 运算符一样,该语句只能在一个{{jsxref("Statements/async_function", "async function", "异步函数", 1)}} 内部使用。

+ +
+

for await...of 不适用于不是异步可迭代的异步迭代器。

+
+ + + +

语法

+ +
for await (variable of iterable) {
+  statement
+}
+
+ +
+
variable
+
在每次迭代中,将不同属性的值分配给变量。变量有可能以constlet, 或者 var来声明。
+
iterable
+
被迭代枚举其属性的对象。与 for...of 相比,这里的对象可以返回 Promise,如果是这样,那么 variable 将是 Promise 所包含的值,否则是值本身。
+
+ +

例子

+ +

迭代异步可迭代对象

+ +

你还可以迭代一个明确实现异步迭代协议的对象:

+ +
var asyncIterable = {
+  [Symbol.asyncIterator]() {
+    return {
+      i: 0,
+      next() {
+        if (this.i < 3) {
+          return Promise.resolve({ value: this.i++, done: false });
+        }
+
+        return Promise.resolve({ done: true });
+      }
+    };
+  }
+};
+
+(async function() {
+   for await (num of asyncIterable) {
+     console.log(num);
+   }
+})();
+
+// 0
+// 1
+// 2
+
+ +

迭代异步生成器 

+ +

异步生成器已经实现了异步迭代器协议, 所以可以用 for await...of循环。

+ +
async function* asyncGenerator() {
+  var i = 0;
+  while (i < 3) {
+    yield i++;
+  }
+}
+
+(async function() {
+  for await (num of asyncGenerator()) {
+    console.log(num);
+  }
+})();
+// 0
+// 1
+// 2
+ +

有关使用for await... of考虑迭代API中获取数据的异步 generator 更具体的例子。这个例子首先为一个数据流创建了一个异步 generator,然后使用它来获得这个API的响应值的大小。

+ +
async function* streamAsyncIterator(stream) {
+  const reader = stream.getReader();
+  try {
+    while (true) {
+      const { done, value } = await reader.read();
+      if (done) {
+        return;
+      }
+      yield value;
+    }
+  } finally {
+    reader.releaseLock();
+  }
+}
+// 从url获取数据并使用异步 generator 来计算响应值的大小
+async function getResponseSize(url) {
+  const response = await fetch(url);
+  // Will hold the size of the response, in bytes.
+  let responseSize = 0;
+  // 使用for-await-of循环. 异步 generator 会遍历响应值的每一部分
+  for await (const chunk of streamAsyncIterator(response.body)) {
+    // Incrementing the total response length.
+    responseSize += chunk.length;
+  }
+
+  console.log(`Response Size: ${responseSize} bytes`);
+  // expected output: "Response Size: 1071472"
+  return responseSize;
+}
+getResponseSize('https://jsonplaceholder.typicode.com/photos');
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'ECMAScript Language: The for-in, for-of, and for-await-of Statements')}}{{Spec2('ESDraft')}}
{{SpecName('ES2018', '#sec-for-in-and-for-of-statements', 'ECMAScript Language: The for-in, for-of, and for-await-of Statements')}}{{Spec2('ES2018')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.for_await_of")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/for...in/index.html b/files/zh-cn/web/javascript/reference/statements/for...in/index.html new file mode 100644 index 0000000000..91575e3233 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/for...in/index.html @@ -0,0 +1,157 @@ +--- +title: for...in +slug: Web/JavaScript/Reference/Statements/for...in +tags: + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/for...in +--- +
{{jsSidebar("Statements")}}
+ +

for...in语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性。

+ +

语法

+ +
for (variable in object)
+  statement
+ +
+
variable
+
在每次迭代时,variable会被赋值为不同的属性名。
+
+ +
+
object
+
非Symbol类型的可枚举属性被迭代的对象。
+
+ +

+ +

数组迭代和 for...in

+ +
+

提示:for...in不应该用于迭代一个关注索引顺序的 {{jsxref("Array")}}。

+
+ +

仅迭代自身的属性

+ +

如果你只要考虑对象本身的属性,而不是它的原型,那么使用 {{jsxref("Object.getOwnPropertyNames", "getOwnPropertyNames()")}} 或执行 {{jsxref("Object.prototype.hasOwnProperty", "hasOwnProperty()")}} 来确定某属性是否是对象本身的属性(也能使用{{jsxref("Object.prototype.propertyIsEnumerable", "propertyIsEnumerable")}})。或者,如果你知道不会有任何外部代码干扰,您可以使用检查方法扩展内置原型。

+ +

为什么用for ... in?

+ +

for ... in是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()for ... of,那么for ... in的到底有什么用呢?

+ +

它最常用的地方应该是用于调试,可以更方便的去检查对象属性(通过输出到控制台或其他方式)。尽管对于处理存储数据,数组更实用些,但是你在处理有key-value数据(比如属性用作“键”),需要检查其中的任何键是否为某值的情况时,还是推荐用for ... in

+ +

示例

+ +

下面的函数接受一个对象作为参数。被调用时迭代传入对象的所有可枚举属性然后返回一个所有属性名和其对应值的字符串。

+ +
var obj = {a:1, b:2, c:3};
+
+for (var prop in obj) {
+  console.log("obj." + prop + " = " + obj[prop]);
+}
+
+// Output:
+// "obj.a = 1"
+// "obj.b = 2"
+// "obj.c = 3"
+ +

下面的函数说明了{{jsxref("Object.prototype.hasOwnProperty", "hasOwnProperty()")}}的用法:继承的属性不显示。

+ +
var triangle = {a: 1, b: 2, c: 3};
+
+function ColoredTriangle() {
+  this.color = 'red';
+}
+
+ColoredTriangle.prototype = triangle;
+
+var obj = new ColoredTriangle();
+
+for (var prop in obj) {
+  if (obj.hasOwnProperty(prop)) {
+    console.log(`obj.${prop} = ${obj[prop]}`);
+  }
+}
+
+// Output:
+// "obj.color = red"
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'for...in statement')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-for-in-and-for-of-statements', 'for...in statement')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-12.6.4', 'for...in statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-12.6.4', 'for...in statement')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-12.6.3', 'for...in statement')}}{{Spec2('ES1')}}Initial definition.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.for_in")}}

+ +

兼容性:初始化函数表达式

+ +

在 SpiderMonkey 40 {{geckoRelease(40)}} 版本之前,可以在使用一个初始化表达式(i=0)在一个for...in循环中:

+ +
var obj = {a: 1, b: 2, c: 3};
+for (var i = 0 in obj) {
+  console.log(obj[i]);
+}
+// 1
+// 2
+// 3
+
+ +

这个非标准行为现在在版本40及更高版本中被忽略,并将在严格模式({{bug(748550)}} 和 {{bug(1164741)}})中呈现{{jsxref("SyntaxError")}}("for-in loop head declarations may not have initializers")错误。

+ +

像其他引擎 V8(Chrome),Chakra (IE/Edge), JSC (WebKit/Safari) 正在研究去除这种不标准的行为。

+ +

相关链接

+ + + +
+
+
diff --git a/files/zh-cn/web/javascript/reference/statements/for...of/index.html b/files/zh-cn/web/javascript/reference/statements/for...of/index.html new file mode 100644 index 0000000000..49152b716f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/for...of/index.html @@ -0,0 +1,313 @@ +--- +title: for...of +slug: Web/JavaScript/Reference/Statements/for...of +tags: + - ECMAScript 2015 + - JavaScript + - Reference + - Statement +translation_of: Web/JavaScript/Reference/Statements/for...of +--- +
+
{{jsSidebar("Statements")}}
+
+ +

for...of语句可迭代对象(包括 {{jsxref("Array")}},{{jsxref("Map")}},{{jsxref("Set")}},{{jsxref("String")}},{{jsxref("TypedArray")}},arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

+ +
{{EmbedInteractiveExample("pages/js/statement-forof.html")}}
+ + + +

语法

+ +
for (variable of iterable) {
+    //statements
+}
+
+ +
+
variable
+
在每次迭代中,将不同属性的值分配给变量。
+
iterable
+
被迭代枚举其属性的对象。
+
+ +

示例

+ +

迭代{{jsxref("Array")}}

+ +
let iterable = [10, 20, 30];
+
+for (let value of iterable) {
+    value += 1;
+    console.log(value);
+}
+// 11
+// 21
+// 31
+
+ +

如果你不想修改语句块中的变量 , 也可以使用const代替let

+ +
let iterable = [10, 20, 30];
+
+for (const value of iterable) {
+  console.log(value);
+}
+// 10
+// 20
+// 30
+ +

迭代{{jsxref("String")}}

+ +
let iterable = "boo";
+
+for (let value of iterable) {
+  console.log(value);
+}
+// "b"
+// "o"
+// "o"
+ +

迭代 {{jsxref("TypedArray")}}

+ +
let iterable = new Uint8Array([0x00, 0xff]);
+
+for (let value of iterable) {
+  console.log(value);
+}
+// 0
+// 255
+
+ +

迭代{{jsxref("Map")}}

+ +
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);
+
+for (let entry of iterable) {
+  console.log(entry);
+}
+// ["a", 1]
+// ["b", 2]
+// ["c", 3]
+
+for (let [key, value] of iterable) {
+  console.log(value);
+}
+// 1
+// 2
+// 3
+
+ +

迭代 {{jsxref("Set")}}

+ +
let iterable = new Set([1, 1, 2, 2, 3, 3]);
+
+for (let value of iterable) {
+  console.log(value);
+}
+// 1
+// 2
+// 3
+ +

迭代 {{jsxref("arguments")}} 对象

+ +
(function() {
+  for (let argument of arguments) {
+    console.log(argument);
+  }
+})(1, 2, 3);
+
+// 1
+// 2
+// 3
+ +

迭代 DOM 集合

+ +

迭代 DOM 元素集合,比如一个{{domxref("NodeList")}}对象:下面的例子演示给每一个 article 标签内的 p 标签添加一个 "read" 类。

+ +
//注意:这只能在实现了NodeList.prototype[Symbol.iterator]的平台上运行
+let articleParagraphs = document.querySelectorAll("article > p");
+
+for (let paragraph of articleParagraphs) {
+  paragraph.classList.add("read");
+}
+
+ +

关闭迭代器

+ +

对于for...of的循环,可以由breakthrow  continue    或return终止。在这些情况下,迭代器关闭。

+ +
function* foo(){
+  yield 1;
+  yield 2;
+  yield 3;
+};
+
+for (let o of foo()) {
+  console.log(o);
+  break; // closes iterator, triggers return
+}
+
+ +

迭代生成器

+ +

你还可以迭代一个生成器

+ +
function* fibonacci() { // 一个生成器函数
+    let [prev, curr] = [0, 1];
+    for (;;) { // while (true) {
+        [prev, curr] = [curr, prev + curr];
+        yield curr;
+    }
+}
+
+for (let n of fibonacci()) {
+     console.log(n);
+    // 当n大于1000时跳出循环
+    if (n >= 1000)
+        break;
+}
+ +

不要重用生成器

+ +

生成器不应该重用,即使for...of循环的提前终止,例如通过{{jsxref("Statements/break", "break")}}关键字。在退出循环后,生成器关闭,并尝试再次迭代,不会产生任何进一步的结果。

+ +
var gen = (function *(){
+    yield 1;
+    yield 2;
+    yield 3;
+})();
+for (let o of gen) {
+    console.log(o);
+    break;//关闭生成器
+}
+
+//生成器不应该重用,以下没有意义!
+for (let o of gen) {
+    console.log(o);
+}
+
+
+ +

迭代其他可迭代对象

+ +

你还可以迭代显式实现可迭代协议的对象:

+ +
var iterable = {
+  [Symbol.iterator]() {
+    return {
+      i: 0,
+      next() {
+        if (this.i < 3) {
+          return { value: this.i++, done: false };
+        }
+        return { value: undefined, done: true };
+      }
+    };
+  }
+};
+
+for (var value of iterable) {
+  console.log(value);
+}
+// 0
+// 1
+// 2
+ +

for...offor...in的区别

+ +

无论是for...in还是for...of语句都是迭代一些东西。它们之间的主要区别在于它们的迭代方式。

+ +

{{jsxref("Statements/for...in", "for...in")}} 语句以任意顺序迭代对象的可枚举属性

+ +

for...of 语句遍历可迭代对象定义要迭代的数据。

+ +

以下示例显示了与{{jsxref("Array")}}一起使用时,for...of循环和for...in循环之间的区别。

+ +
Object.prototype.objCustom = function() {};
+Array.prototype.arrCustom = function() {};
+
+let iterable = [3, 5, 7];
+iterable.foo = 'hello';
+
+for (let i in iterable) {
+  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
+}
+
+for (let i in iterable) {
+  if (iterable.hasOwnProperty(i)) {
+    console.log(i); // logs 0, 1, 2, "foo"
+  }
+}
+
+for (let i of iterable) {
+  console.log(i); // logs 3, 5, 7
+}
+ +
Object.prototype.objCustom = function() {};
+Array.prototype.arrCustom = function() {};
+
+let iterable = [3, 5, 7];
+iterable.foo = 'hello';
+
+ +

每个对象将继承objCustom属性,并且作为{{jsxref("Array")}}的每个对象将继承arrCustom属性,因为将这些属性添加到{{jsxref("Object.prototype")}}和{{jsxref("Array.prototype")}}。由于继承和原型链,对象iterable继承属性objCustomarrCustom

+ +
for (let i in iterable) {
+  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
+}
+
+ +

此循环仅以原始插入顺序记录iterable 对象的可枚举属性。它不记录数组元素357 或hello,因为这些不是枚举属性。但是它记录了数组索引以及arrCustomobjCustom。如果你不知道为什么这些属性被迭代,{{jsxref("Statements/for...in", "array iteration and for...in", "#Array_iteration_and_for...in")}}中有更多解释。

+ +
for (let i in iterable) {
+  if (iterable.hasOwnProperty(i)) {
+    console.log(i); // logs 0, 1, 2, "foo"
+  }
+}
+
+ +

这个循环类似于第一个,但是它使用{{jsxref("Object.prototype.hasOwnProperty()", "hasOwnProperty()")}} 来检查,如果找到的枚举属性是对象自己的(不是继承的)。如果是,该属性被记录。记录的属性是012foo,因为它们是自身的属性(不是继承的)。属性arrCustomobjCustom不会被记录,因为它们是继承的

+ +
for (let i of iterable) {
+  console.log(i); // logs 3, 5, 7
+}
+
+ +

该循环迭代并记录iterable作为可迭代对象定义的迭代值,这些是数组元素 357,而不是任何对象的属性

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-for-in-and-for-of-statements', 'for...of statement')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'for...of statement')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.for_of")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/for/index.html b/files/zh-cn/web/javascript/reference/statements/for/index.html new file mode 100644 index 0000000000..0a904c3473 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/for/index.html @@ -0,0 +1,169 @@ +--- +title: for +slug: Web/JavaScript/Reference/Statements/for +tags: + - JavaScript + - Loop + - Reference + - Statement + - for +translation_of: Web/JavaScript/Reference/Statements/for +--- +
{{jsSidebar("Statements")}}
+ +

for 语句用于创建一个循环,它包含了三个可选的表达式,这三个表达式被包围在圆括号之中,使用分号分隔,后跟一个用于在循环中执行的语句(通常是一个块语句)。

+ +
{{EmbedInteractiveExample("pages/js/statement-for.html")}}
+ + + +

语法

+ +
for ([initialization]; [condition]; [final-expression])
+   statement
+
+ +
+
initialization
+
一个表达式 (包含赋值语句) 或者变量声明。典型地被用于初始化一个计数器。该表达式可以使用 varlet 关键字声明新的变量,使用 var 声明的变量不是该循环的局部变量,而是与 for 循环处在同样的作用域中。用 let 声明的变量是语句的局部变量。该表达式的结果无意义。
+
condition
+
一个条件表达式被用于确定每一次循环是否能被执行。如果该表达式的结果为 true,statement 将被执行。这个表达式是可选的。如果被忽略,那么就被认为永远为真。如果计算结果为假,那么执行流程将被跳到 for 语句结构后面的第一条语句。
+
final-expression
+
每次循环的最后都要执行的表达式。执行时机是在下一次 condition 的计算之前。通常被用于更新或者递增计数器变量。
+
statement
+
只要condition的结果为true就会被执行的语句。要在循环体内执行多条语句,使用一个块语句{ ... })来包含要执行的语句。没有任何语句要执行,使用一个空语句;)。
+
+ +

示例

+ +

使用 for

+ +

以下例子声明了变量 i 并被初始赋值为 0for 语句检查 i 的值是否小于 9,如果小于 9,则执行语句块内的语句,并且最后将 i 的值增加 1。

+ +
for (var i = 0; i < 9; i++) {
+   console.log(i);
+   // more statements
+}
+
+ +

可选的 for 表达式

+ +

for 语句头部圆括号中的所有三个表达式都是可选的。

+ +

例如,初始化块中的表达式没有被指定:

+ +
var i = 0;
+for (; i < 9; i++) {
+    console.log(i);
+    // more statements
+}
+
+ +

像初始化块一样,条件块也是可选的。如果省略此表达式,则必须确保在循环体内跳出,以防创建死循环。

+ +
for (var i = 0;; i++) {
+   console.log(i);
+   if (i > 3) break;
+   // more statements
+}
+ +

你当然可以忽略所有的表达式。同样的,确保使用了 {{jsxref("Statements/break", "break")}} >语句来跳出循环并且还要修改(增加)一个变量,使得 break 语句的条件在某个时候是真的。

+ +
var i = 0;
+
+for (;;) {
+  if (i > 3) break;
+  console.log(i);
+  i++;
+}
+
+ +

使用无语句的 for

+ +

以下 for 循环计算 final-expression 部分中节点的偏移位置,它不需要执行一个 statement 或者一组 block statement ,因此使用了空语句。

+ +
function showOffsetPos(sId) {
+
+  var nLeft = 0, nTop = 0;
+
+  for (
+
+    var oItNode = document.getElementById(sId); /* initialization */
+
+    oItNode; /* condition */
+
+    nLeft += oItNode.offsetLeft, nTop += oItNode.offsetTop, oItNode = oItNode.offsetParent /* final-expression */
+
+  ); /* 分号 semicolon */
+
+  console.log('Offset position of \'' + sId + '\' element:\n left: ' + nLeft + 'px;\n top: ' + nTop + 'px;');
+
+}
+
+/* Example call: */
+
+showOffsetPos('content');
+
+// Output:
+// "Offset position of "content" element:
+// left: 0px;
+// top: 153px;"
+ +
+

提示:这里的分号是强制性的,是 JavaScript 中的少数几种强制分号的情况。如果没有分号,循环声明之后的行将被视为循环语句。

+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-for-statement', 'for statement')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-for-statement', 'for statement')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-12.6.3', 'for statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-12.6.3', 'for statement')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-12.6.2', 'for statement')}}{{Spec2('ES1')}}Initial definition
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.for")}}

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/for_each...in/index.html b/files/zh-cn/web/javascript/reference/statements/for_each...in/index.html new file mode 100644 index 0000000000..05c1043588 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/for_each...in/index.html @@ -0,0 +1,69 @@ +--- +title: for each...in +slug: Web/JavaScript/Reference/Statements/for_each...in +translation_of: Archive/Web/JavaScript/for_each...in +--- +
{{jsSidebar("Statements")}}
+ +

使用一个变量迭代一个对象的所有属性值,对于每一个属性值,有一个指定的语句块被执行。

+ +
+
+

作为ECMA-357(E4X)标准的一部分,for each...in语句已被废弃,E4X中的大部分特性已被删除,但考虑到向后兼容,for each...in只会被禁用而不会被删除,可以使用ES6中新的for...of语句来代替。({{ bug("791343")}}.)

+
+ +
for each...inECMA-357 (E4X) 标准的一部分,大部分非Mozilla浏览器都没有实现该标准,E4X并不是 ECMAScript 标准的一部分。
+
+ +

语法

+ +
for each (variable in object) {
+  statement
+}
+ +

参数

+ +
+
variable
+
用来遍历属性值的变量,前面的var关键字是可选的。该变量是函数的局部变量而不是语句块的局部变量。
+
+ +
+
object
+
属性值会被遍历的对象。
+
+ +
+
statement
+
遍历属性时执行的语句。如果想要执行多条语句,请用块语句({ ... }) 将多条语句括住。
+
+ +

描述

+ +

一些对象的内置属性是无法被遍历到的,包括所有的内置方法,例如String对象的indexOf方法。不过,大部分的用户自定义属性都是可遍历的.

+ +

示例

+ +

例子: 使用for each...in

+ +

警告:永远不要使用for each...in语句遍历数组,仅用来遍历常规对象。这里讲解了为什么这么说

+ +

下面的代码片段演示如何遍历一个对象的属性值,并计算它们的和:

+ +
var sum = 0;
+var obj = {prop1: 5, prop2: 13, prop3: 8};
+
+for each (var item in obj) {
+  sum += item;
+}
+
+print(sum); // 输出"26",也就是5+13+8的值
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/function/index.html b/files/zh-cn/web/javascript/reference/statements/function/index.html new file mode 100644 index 0000000000..b53c1891b8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/function/index.html @@ -0,0 +1,179 @@ +--- +title: function +slug: Web/JavaScript/Reference/Statements/function +tags: + - 函数 + - 函数声明提升 + - 函数表达式 + - 提升 + - 语句 +translation_of: Web/JavaScript/Reference/Statements/function +--- +
{{jsSidebar("Statements")}}
+ +

函数声明定义一个具有指定参数的函数。

+ +
+

你还可以使用  {{jsxref("Function")}} 构造函数和 一个{{jsxref("Operators/function", "function expression")}} 定义函数。

+
+ + + +

语法

+ +
function name([param,[, param,[..., param]]]) {
+   [statements]
+}
+
+ +
+
name
+
函数名
+
+ +
+
param
+
要传递给函数的参数的名称。不同引擎中的最大参数数量不同。
+
+ +
+
statements
+
包含函数体的语句。
+
+ +

描述

+ +

一个被函数声明创建的函数是一个 Function 对象,具有 Function 对象的所有属性、方法和行为。查看 Function 以获取 function 的详细信息。

+ +

函数也可以被表达式创建( function expression )

+ +

函数可以被有条件来声明,这意味着,在一个 if 语句里,函数声明是可以嵌套的。有的浏览器会将这种有条件的声明看成是无条件的声明,无论这里的条件是true还是false,浏览器都会创建函数。因此,它们不应该被使用。

+ +

默认情况下,函数是返回 undefined 的。想要返回一个其他的值,函数必须通过一个 return 语句指定返回值。

+ +

有条件的创建函数

+ +

函数可以被有条件来声明,这意味着,函数声明可能出现在一个 if 语句里,但是,这种声明方式在不同的浏览器里可能有不同的效果。因此,不应该在生成环境代码中使用这种声明方式,应该使用函数表达式来代替。

+ +
var hoisted = "foo" in this;
+console.log(`'foo' name ${hoisted ? "is" : "is not"} hoisted. typeof foo is ${typeof foo}`);
+if (false) {
+  function foo(){ return 1; }
+}
+
+// 在Chrome里:
+// 'foo' 变量名被提升,但是 typeof foo 为 undefined
+//
+// 在Firefox里:
+// 'foo' 变量名被提升. 但是 typeof foo 为 undefined
+//
+// 在Edge里:
+// 'foo' 变量名未被提升. 而且 typeof foo 为 undefined
+//
+// 在Safari里:
+// 'foo' 变量名被提升. 而且 typeof foo 为 function
+ +

注意,即使把上面代码中的 if(false) 改为 if(true),结果也是一样的

+ +
var hoisted = "foo" in this;
+console.log(`'foo' name ${hoisted ? "is" : "is not"} hoisted. typeof foo is ${typeof foo}`);
+if (true) {
+  function foo(){ return 1; }
+}
+
+// 在Chrome里:
+// 'foo' 变量名被提升,但是 typeof foo 为 undefined
+//
+// 在Firefox里:
+// 'foo' 变量名被提升. 但是 typeof foo 为 undefined
+//
+// 在Edge里:
+// 'foo' 变量名未被提升. 而且 typeof foo 为 undefined
+//
+// 在Safari里:
+// 'foo' 变量名被提升. 而且 typeof foo 为 function
+
+ +

函数声明提升

+ +

JavaScript 中的函数声明被提升到了函数定义。你可以在函数声明之前使用该函数:

+ +
hoisted(); // "foo"
+
+function hoisted() {
+     console.log("foo");
+}
+
+/* equal to*/
+var hoisted; 
+
+hoisted = function() {
+  console.log("foo");
+}
+hoisted();
+// "foo" 
+
+ +
+

注意 :函数表达式{{jsxref("Operators/function", "function expressions")}} 不会被提升:

+
+ +
notHoisted(); // TypeError: notHoisted is not a function
+
+var notHoisted = function() {
+   console.log("bar");
+};
+ +

示例

+ +

使用函数

+ +

下面的代码声明了一个函数,该函数返回了销售的总金额, 参数是产品a,b,c分别的销售的数量.

+ +
function calc_sales(units_a, units_b, units_c) {
+   return units_a*79 + units_b * 129 + units_c * 699;
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.0
{{SpecName('ES5.1', '#sec-13', 'Function definition')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.function")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/function_star_/index.html b/files/zh-cn/web/javascript/reference/statements/function_star_/index.html new file mode 100644 index 0000000000..4e1f69883a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/function_star_/index.html @@ -0,0 +1,242 @@ +--- +title: function* +slug: Web/JavaScript/Reference/Statements/function* +tags: + - ECMAScript 2015 + - Generator + - JavaScript + - function* + - 函数 + - 声明 + - 迭代器 +translation_of: Web/JavaScript/Reference/Statements/function* +--- +
{{jsSidebar("Statements")}}
+ +

function* 这种声明方式(function关键字后跟一个星号)会定义一个生成器函数 (generator function),它返回一个  {{jsxref("Global_Objects/Generator","Generator")}}  对象。

+ +
{{EmbedInteractiveExample("pages/js/statement-functionasterisk.html")}}
+ + + +
+

你也可以使用构造函数  {{jsxref("GeneratorFunction")}} 或 {{jsxref("Operators/function*", "function* expression")}} 定义生成器函数

+
+ +

语法

+ +
function* name([param[, param[, ... param]]]) { statements }
+
+ +
+
name
+
函数名
+
+ +
+
param
+
要传递给函数的一个参数的名称,一个函数最多可以有255个参数。
+
+ +
+
statements
+
普通JS语句。
+
+ +

描述

+ +

生成器函数在执行时能暂停,后面又能从暂停处继续执行。

+ +

调用一个生成器函数并不会马上执行它里面的语句,而是返回一个这个生成器的 迭代器 ( iterator )对象。当这个迭代器的 next() 方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现{{jsxref("Operators/yield", "yield")}}的位置为止,{{jsxref("Operators/yield", "yield")}} 后紧跟迭代器要返回的值。或者如果用的是 {{jsxref("Operators/yield*", "yield*")}}(多了个星号),则表示将执行权移交给另一个生成器函数(当前生成器暂停执行)。

+ +

next()方法返回一个对象,这个对象包含两个属性:value 和 done,value 属性表示本次 yield 表达式的返回值,done 属性为布尔类型,表示生成器后续是否还有 yield 语句,即生成器函数是否已经执行完毕并返回。

+ +

调用 next()方法时,如果传入了参数,那么这个参数会传给上一条执行的 yield语句左边的变量,例如下面例子中的 x

+ +
function *gen(){
+    yield 10;
+    x=yield 'foo';
+    yield x;
+}
+
+var gen_obj=gen();
+console.log(gen_obj.next());// 执行 yield 10,返回 10
+console.log(gen_obj.next());// 执行 yield 'foo',返回 'foo'
+console.log(gen_obj.next(100));// 将 100 赋给上一条 yield 'foo' 的左值,即执行 x=100,返回 100
+console.log(gen_obj.next());// 执行完毕,value 为 undefined,done 为 true
+ +

当在生成器函数中显式 return 时,会导致生成器立即变为完成状态,即调用 next() 方法返回的对象的 done true。如果 return 后面跟了一个值,那么这个值会作为当前调用 next() 方法返回的 value 值。

+ +

示例

+ +

简单示例

+ +
function* idMaker(){
+  var index = 0;
+  while(index<3)
+    yield index++;
+}
+
+var gen = idMaker();
+console.log(gen.next().value); // 0
+console.log(gen.next().value); // 1
+console.log(gen.next().value); // 2
+console.log(gen.next().value); // undefined
+
+ +

生成器也可以接收参数:

+ +
function* idMaker(){
+    var index = arguments[0] || 0;
+    while(true)
+        yield index++;
+}
+
+var gen = idMaker(5);
+console.log(gen.next().value); // 5
+console.log(gen.next().value); // 6
+ +

yield*的示例

+ +
function* anotherGenerator(i) {
+  yield i + 1;
+  yield i + 2;
+  yield i + 3;
+}
+
+function* generator(i){
+  yield i;
+  yield* anotherGenerator(i);// 移交执行权
+  yield i + 10;
+}
+
+var gen = generator(10);
+
+console.log(gen.next().value); // 10
+console.log(gen.next().value); // 11
+console.log(gen.next().value); // 12
+console.log(gen.next().value); // 13
+console.log(gen.next().value); // 20
+
+ +

传递参数

+ +
function *createIterator() {
+    let first = yield 1;
+    let second = yield first + 2; // 4 + 2
+                                  // first =4 是next(4)将参数赋给上一条的
+    yield second + 3;             // 5 + 3
+}
+
+let iterator = createIterator();
+
+console.log(iterator.next());    // "{ value: 1, done: false }"
+console.log(iterator.next(4));   // "{ value: 6, done: false }"
+console.log(iterator.next(5));   // "{ value: 8, done: false }"
+console.log(iterator.next());    // "{ value: undefined, done: true }"
+ +

显式返回

+ +
function* yieldAndReturn() {
+  yield "Y";
+  return "R";//显式返回处,可以观察到 done 也立即变为了 true
+  yield "unreachable";// 不会被执行了
+}
+
+var gen = yieldAndReturn()
+console.log(gen.next()); // { value: "Y", done: false }
+console.log(gen.next()); // { value: "R", done: true }
+console.log(gen.next()); // { value: undefined, done: true }
+ +

生成器函数不能当构造器使用

+ +
function* f() {}
+var obj = new f; // throws "TypeError: f is not a constructor"
+ +

使用迭代器遍历二维数组并转换成一维数组:

+ +
+
function* iterArr(arr) {            //迭代器返回一个迭代器对象
+  if (Array.isArray(arr)) {         // 内节点
+      for(let i=0; i < arr.length; i++) {
+          yield* iterArr(arr[i]);   // (*)递归
+      }
+  } else {                          // 离开
+      yield arr;
+  }
+}
+// 使用 for-of 遍历:
+var arr = ['a', ['b', 'c'], ['d', 'e']];
+for(var x of iterArr(arr)) {
+        console.log(x);               // a  b  c  d  e
+ }
+
+// 或者直接将迭代器展开:
+var arr = [ 'a', ['b',[ 'c', ['d', 'e']]]];
+var gen = iterArr(arr);
+arr = [...gen];                        // ["a", "b", "c", "d", "e"]
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#', 'function*')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#', 'function*')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.statements.generator_function")}} 

+
+ +

Firefox浏览器具体事项

+ +

Firefox 26之前的生成器和迭代器

+ +

旧版本的Firefox实施了旧版本的生成器提案。旧版中用普通的function关键字定义(没有星号).

+ +

IteratorResult不再抛出错误

+ +

从Gecko 29 {{geckoRelease(29)}}开始,完成的生成器函数不再抛出{{jsxref("TypeError")}} "generator has already finished". 而是返回一个IteratorResult对象:{ value: undefined, done: true } ({{bug(958951)}})。

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/if...else/index.html b/files/zh-cn/web/javascript/reference/statements/if...else/index.html new file mode 100644 index 0000000000..90d29e86ae --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/if...else/index.html @@ -0,0 +1,176 @@ +--- +title: if...else +slug: Web/JavaScript/Reference/Statements/if...else +tags: + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/if...else +--- +
+
 {{jsSidebar("Statements")}}
+
+ +

当指定条件为真,if 语句会执行一段语句。如果条件为假,则执行另一段语句。

+ +

{{EmbedInteractiveExample("pages/js/statement-ifelse.html")}}

+ + + +

语法

+ +
if (condition)
+   statement1
+[else
+   statement2]
+
+ +
+
condition
+
值为真或假的表达式
+
+ +
+
statement1
+
condition为真时执行的语句。可为任意语句,包括更深层的内部if语句。要执行多条语句,使用语句({ ... })将这些语句分组;若不想执行语句,则使用语句。 
+
+ +
+
statement2
+
如果condition为假且 else从句存在时执行的语句。可为任意语句,包括块语句和嵌套的if语句
+
+ +

说明

+ +

多层 if...else 语句可使用 else if 从句。注意:在 Javascript 中没有 elseif (一个单词)关键字。

+ +
if (condition1)
+   statement1
+else if (condition2)
+   statement2
+else if (condition3)
+   statement3
+...
+else
+   statementN
+
+
+ +

要看看它如何工作,可以调整下嵌套的缩进:

+ +
if (condition1)
+   statement1
+else
+   if (condition2)
+      statement2
+   else
+      if (condition3)
+...
+
+ +

要在一个从句中执行多条语句,可使用语句块({ ... })。通常情况下,一直使用语句块是个好习惯,特别是在涉及嵌套if语句的代码中:

+ +
if (condition) {
+   statements1
+} else {
+   statements2
+}
+
+ +

不要将原始布尔值的truefalseBoolean对象的真或假混淆。任何一个值,只要它不是 undefinednull、 0NaN或空字符串(""),那么无论是任何对象,即使是值为假的Boolean对象,在条件语句中都为真。例如:

+ +
var b = new Boolean(false);
+if (b) //表达式的值为true
+
+ +

示例

+ +

使用 if...else

+ +
if (cipher_char === from_char) {
+   result = result + to_char;
+   x++;
+} else {
+   result = result + clear_char;
+}
+
+ +

使用 else if

+ +

注意,Javascript中没有elseif语句。但可以使用elseif中间有空格的语句:

+ +
if (x > 5) {
+ /* do the right thing */
+} else if (x > 50) {
+ /* do the right thing */
+} else {
+ /* do the right thing */
+}
+ +

条件表达式中的赋值运算

+ +

建议不要在条件表达式中单纯的使用赋值运算,因为粗看下赋值运算的代码很容易让人误认为是等性比较。比如,不要使用下面示例的代码:

+ +
if (x = y) {
+   /* do the right thing */
+}
+
+ +

如果你需要在条件表达式中使用赋值运算,用圆括号包裹赋值运算。例如:

+ +
if ((x = y)) {
+   /* do the right thing */
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-if-statement', 'if statement')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-if-statement', 'if statement')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-12.5', 'if statement')}}{{Spec2('ES5.1')}} 
{{SpecName('ES3', '#sec-12.5', 'if statement')}}{{Spec2('ES3')}} 
{{SpecName('ES1', '#sec-12.5', 'if statement')}}{{Spec2('ES1')}}Initial definition
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.if_else")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/import.meta/index.html b/files/zh-cn/web/javascript/reference/statements/import.meta/index.html new file mode 100644 index 0000000000..95f5f68e36 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/import.meta/index.html @@ -0,0 +1,104 @@ +--- +title: import.meta +slug: Web/JavaScript/Reference/Statements/import.meta +tags: + - JavaScript + - Language feature + - Modules + - Reference + - Statement + - import +translation_of: Web/JavaScript/Reference/Statements/import.meta +--- +
{{JSSidebar("Statements")}}
+ +

import.meta是一个给JavaScript模块暴露特定上下文的元数据属性的对象。它包含了这个模块的信息,比如说这个模块的URL。

+ +

语法

+ +
import.meta
+ +

描述

+ +

import.meta对象由一个关键字"import",一个点符号和一个meta属性名组成。通常情况下"import."是作为一个属性访问的上下文,但是在这里"import"不是一个真正的对象。

+ +

import.meta对象是由ECMAScript实现的,它带有一个{{jsxref("null")}}的原型对象。这个对象可以扩展,并且它的属性都是可写,可配置和可枚举的。

+ +

示例

+ +

这里有一个 my-module.mjs模块

+ +
<script type="module" src="my-module.mjs"></script>
+
+ +

你可以通过 import.meta 对象获取这个模块的元数据信息.

+ +
console.log(import.meta); // { url: "file:///home/user/my-module.mjs" }
+ +

它返回一个带有url属性的对象,指明模块的基本URL。也可以是外部脚本的URL,还可以是内联脚本所属文档的URL。

+ +

注意,url也可能包含参数或者哈希(比如后缀?#

+ +

以下面的HTML为例:

+ +
<script type="module">
+import './index.mjs?someURLInfo=5';
+</script>
+ +

...下面的JavaScript会打印someURLInfo这个参数:

+ +
// index.mjs
+new URL(import.meta.url).searchParams.get('someURLInfo'); // 5
+ +

在脚本中引入别的脚本同样生效:

+ +
// index.mjs
+import './index2.mjs?someURLInfo=5';
+
+// index2.mjs
+new URL(import.meta.url).searchParams.get('someURLInfo'); // 5
+ +

虽然在上述例子中,Node.js允许携带参数(或哈希),但以Node 14.1.0为例,使用node --experimental-modules index.mjs?someURLInfo=5 执行脚本,查询URL参数将会报错(该环境下index.mjs?someURLInfo=5 被视作一个文件而不是URL)

+ +

像这种特定于文件的参数传递可能是对应用范围内location.href(ps: 通过在HTML路径添加参数或哈希)(而在Node.js中是process.env)的补充

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
tc39/proposal-import-metaStage 3Initial definition.
HTML StandardLiving StandardDefines import.meta properties in HTML.
+ +

浏览器支持

+ + + +

{{Compat("javascript.statements.import_meta")}}

+ +

Implementation Progress

+ +

The following table provides a daily implementation status for this feature, because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in Test262, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.

+ +

{{EmbedTest262ReportResultsTable("import.meta")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/import/index.html b/files/zh-cn/web/javascript/reference/statements/import/index.html new file mode 100644 index 0000000000..fabebc11d1 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/import/index.html @@ -0,0 +1,232 @@ +--- +title: import +slug: Web/JavaScript/Reference/Statements/import +tags: + - ECMAScript 2015 + - JavaScript + - Modules + - Statement + - import +translation_of: Web/JavaScript/Reference/Statements/import +--- +

{{jsSidebar("Statements")}}

+ +

静态的import 语句用于导入由另一个模块导出的绑定。无论是否声明了 {{jsxref("Strict_mode","strict mode")}} ,导入的模块都运行在严格模式下。在浏览器中,import 语句只能在声明了 type="module"script 的标签中使用。

+ +

此外,还有一个类似函数的动态 import(),它不需要依赖 type="module" 的script标签。

+ +

script 标签中使用 nomodule 属性,可以确保向后兼容。

+ +

在您希望按照一定的条件或者按需加载模块的时候,动态import() 是非常有用的。而静态型的 import 是初始化加载依赖项的最优选择,使用静态 import 更容易从代码静态分析工具和 tree shaking 中受益。

+ +

语法

+ +
import defaultExport from "module-name";
+import * as name from "module-name";
+import { export } from "module-name";
+import { export as alias } from "module-name";
+import { export1 , export2 } from "module-name";
+import { foo , bar } from "module-name/path/to/specific/un-exported/file";
+import { export1 , export2 as alias2 , [...] } from "module-name";
+import defaultExport, { export [ , [...] ] } from "module-name";
+import defaultExport, * as name from "module-name";
+import "module-name";
+var promise = import("module-name");//这是一个处于第三阶段的提案。
+
+ +
+
defaultExport
+
导入模块的默认导出接口的引用名。
+
module-name
+
要导入的模块。通常是包含目标模块的.js文件的相对或绝对路径名,可以不包括.js扩展名。某些特定的打包工具可能允许或需要使用扩展或依赖文件,它会检查比对你的运行环境。只允许单引号和双引号的字符串。
+
name
+
导入模块对象整体的别名,在引用导入模块时,它将作为一个命名空间来使用。
+
export, exportN
+
被导入模块的导出接口的名称。
+
alias, aliasN
+
将引用指定的导入的名称。
+
+ +

描述

+ +

name参数是“导入模块对象”的名称,它将用一种名称空间来引用导入模块的接口。export参数指定单个的命名导出,而import * as name语法导入所有导出接口,即导入模块整体。以下示例阐明该语法。

+ +

导入整个模块的内容

+ +

这将myModule插入当前作用域,其中包含来自位于/modules/my-module.js文件中导出的所有接口。

+ +
import * as myModule from '/modules/my-module.js';
+
+ +

在这里,访问导出接口意味着使用模块名称(在本例为“myModule”)作为命名空间。例如,如果上面导入的模块包含一个接口doAllTheAmazingThings(),你可以这样调用:

+ +
myModule.doAllTheAmazingThings();
+ +

导入单个接口

+ +

给定一个名为myExport的对象或值,它已经从模块my-module导出(因为整个模块被导出)或显式地导出(使用{{jsxref("Statements/export", "export")}}语句),将myExport插入当前作用域。

+ +
import {myExport} from '/modules/my-module.js';
+ +

导入多个接口

+ +

这将foobar插入当前作用域。

+ +
import {foo, bar} from '/modules/my-module.js';
+ +

导入带有别名的接口

+ +

你可以在导入时重命名接口。例如,将shortName插入当前作用域。

+ +
import {reallyReallyLongModuleExportName as shortName}
+  from '/modules/my-module.js';
+ +

导入时重命名多个接口

+ +

使用别名导入模块的多个接口。

+ +
import {
+  reallyReallyLongModuleMemberName as shortName,
+  anotherLongModuleName as short
+} from '/modules/my-module.js';
+
+ +

仅为副作用而导入一个模块

+ +

整个模块仅为副作用(中性词,无贬义含义)而导入,而不导入模块中的任何内容(接口)。 这将运行模块中的全局代码, 但实际上不导入任何值。

+ +
import '/modules/my-module.js';
+ +

导入默认值

+ +

引入模块可能有一个default{{jsxref("Statements/export", "export")}}(无论它是对象,函数,类等)可用。然后可以使用import语句来导入这样的默认接口。

+ +

最简单的用法是直接导入默认值:

+ +
import myDefault from '/modules/my-module.js';
+ +

也可以同时将default语法与上述用法(命名空间导入或命名导入)一起使用。在这种情况下,default导入必须首先声明。 例如:

+ +
import myDefault, * as myModule from '/modules/my-module.js';
+// myModule used as a namespace
+ +

或者

+ +
import myDefault, {foo, bar} from '/modules/my-module.js';
+// specific, named imports
+
+ +

When importing a default export with {{anch("Dynamic Imports", "dynamic imports")}}, it works a bit differently. You need to destructure and rename the "default" key from the returned object.

+ +
(async () => {
+  if (somethingIsTrue) {
+    const { default: myDefault, foo, bar } = await import('/modules/my-module.js');
+  }
+})();
+ +

动态import

+ +

标准用法的import导入的模块是静态的,会使所有被导入的模块,在加载时就被编译(无法做到按需编译,降低首页加载速度)。有些场景中,你可能希望根据条件导入模块或者按需导入模块,这时你可以使用动态导入代替静态导入。下面的是你可能会需要动态导入的场景:

+ + + +

请不要滥用动态导入(只有在必要情况下采用)。静态框架能更好的初始化依赖,而且更有利于静态分析工具和tree shaking发挥作用

+ +

关键字import可以像调用函数一样来动态的导入模块。以这种方式调用,将返回一个 promise

+ +
import('/modules/my-module.js')
+  .then((module) => {
+    // Do something with the module.
+  });
+
+ +

这种使用方式也支持 await 关键字。

+ +
let module = await import('/modules/my-module.js');
+ +

示例

+ +

标准导入

+ +

下面的代码将会演示如何从辅助模块导入以协助处理AJAX JSON请求。

+ +

模块:file.js

+ +
function getJSON(url, callback) {
+  let xhr = new XMLHttpRequest();
+  xhr.onload = function () {
+    callback(this.responseText)
+  };
+  xhr.open('GET', url, true);
+  xhr.send();
+}
+
+export function getUsefulContents(url, callback) {
+  getJSON(url, data => callback(JSON.parse(data)));
+}
+ +

主程序:main.js

+ +
import { getUsefulContents } from '/modules/file.js';
+
+getUsefulContents('http://www.example.com',
+    data => { doSomethingUseful(data); });
+ +

动态导入

+ +

此示例展示了如何基于用户操作去加载功能模块到页面上,在例子中通过点击按钮,然后会调用模块内的函数。当然这不是能实现这个功能的唯一方式,import()函数也可以支持await

+ +
const main = document.querySelector("main");
+for (const link of document.querySelectorAll("nav > a")) {
+  link.addEventListener("click", e => {
+    e.preventDefault();
+
+    import('/modules/my-module.js')
+      .then(module => {
+        module.loadPageInto(main);
+      })
+      .catch(err => {
+        main.textContent = err.message;
+      });
+  });
+}
+ +

规范

+ + + + + + + + + + + + + + + +
Specification
"function-like" dynamic import() proposal
{{SpecName("ESDraft", "#sec-imports", "Imports")}}
+ +

+ +

{{Compat("javascript.statements.import")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/index.html b/files/zh-cn/web/javascript/reference/statements/index.html new file mode 100644 index 0000000000..c6d70fce55 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/index.html @@ -0,0 +1,150 @@ +--- +title: 语句和声明 +slug: Web/JavaScript/Reference/Statements +tags: + - JavaScript + - 参考 + - 声明 + - 语句和声明 +translation_of: Web/JavaScript/Reference/Statements +--- +
{{jsSidebar("Statements")}}
+ +

JavaScript 应用程序是由许多语法正确的语句组成的。单个语句可以跨多行。如果每个语句用分号隔开,那么多个语句可以在一行中出现。本页的内容并不是一个关键字,而是一组关键字。

+ +

语句和声明(按类别分类)

+ +

若需要按字母顺序排列的列表,请参阅左侧边栏。

+ +

控制流程

+ +
+
{{jsxref("Statements/block", "Block")}}
+
一个块语句可以用来管理零个或多个语句。该区块是由一对大括号分隔。
+
{{jsxref("Statements/break", "break")}}
+
终止当前的循环,switch 或 label 语句,使程序跳到下一个语句执行。
+
{{jsxref("Statements/continue", "continue")}}
+
终止执行当前或标签循环的语句,直接执行下一个迭代循环。
+
{{jsxref("Statements/Empty", "Empty")}}
+
空语句用来表示没有语句的情况,尽管 JavaScript 语法期望有语句提供。
+
{{jsxref("Statements/if...else", "if...else")}}
+
如果指定的条件是 true ,则执行相匹配的一个语句,若为 false,则执行另一个语句。
+
{{jsxref("Statements/switch", "switch")}}
+
计算表达式,将子句于表达式的值做匹配,执行与该值相关联的语句。
+
{{jsxref("Statements/throw", "throw")}}
+
抛出一个用户定义的异常。
+
{{jsxref("Statements/try...catch", "try...catch")}}
+
标记一个语句块,并指定一个应该抛出异常的反馈。(Marks a block of statements to try, and specifies a response, should an exception be thrown.)
+
+ +

声明

+ +
+
{{jsxref("Statements/var", "var")}}
+
声明一个变量,可同时将其初始化为一个值。
+
{{jsxref("Statements/let", "let")}}
+
声明一个块级本地变量,可同时将其初始化为一个值。
+
{{jsxref("Statements/const", "const")}}
+
声明一个只读的命名常量。
+
+ +

函数和类

+ +
+
{{jsxref("Statements/function", "function")}}
+
声明一个指定参数的函数。
+
{{jsxref("Statements/function*", "function*")}}
+
生成器函数使迭代器更容易使用。
+
{{jsxref("Statements/async_function", "async function")}}
+
使用指定的参数声明一个异步函数。
+
{{jsxref("Statements/return", "return")}}
+
指定函数的返回值。
+
{{jsxref("Statements/class", "class")}}
+
声明一个类。
+
+ +

迭代器

+ +
+
{{jsxref("Statements/do...while", "do...while")}}
+
创建一个循环来执行语句,直到该语句条件表达式的值为 false。先执行语句,再执行条件表达式,该语句至少会执行一次。
+
{{jsxref("Statements/for", "for")}}
+
创建一个由3个可选的表达式组成的循环,该循环用括号包裹,分号分割,并在循环体中执行语句。
+
{{jsxref("Statements/for...in", "for...in")}}
+
无序遍历对象的可枚举属性。语句针对每个唯一的属性。
+
{{jsxref("Statements/for...of", "for...of")}}
+
遍历可迭代的对象(包括 {{jsxref("Global_Objects/Array","数组")}}、类数组对象、迭代器和生成器),对每个不同属性的属性,调用一个自定义的有执行语句的迭代钩子。
+
{{jsxref("Statements/for-await...of", "for await...of")}}
+
在异步可迭代对象、类数组对象、迭代器和生成器上迭代,调用自定义迭代钩子,其中包含要为每个不同属性的值执行的语句。
+
{{jsxref("Statements/while", "while")}}
+
创建一个循环语句,循环会一直持续到该语句条件表达式的值为false。先执行条件表达式,然后执行语句。
+
+ +

其他

+ +
+
{{jsxref("Statements/debugger", "debugger")}}
+
调用可用的调试功能。如果没有调试功能可用,该语句不生效。
+
{{jsxref("Statements/export", "export")}}
+
用来导出函数,以便这些函数能够被导入到外部模块或其他脚本中。
+
{{jsxref("Statements/import", "import")}}
+
用来引入外部的模块或另一个script中导出的函数。
+
import.meta
+
向 JavaScript 模块公开上下文特定的元数据的元属性。
+
{{jsxref("Statements/label", "label")}}
+
带标识的语句,与 breakcontinue 语句一起使用。
+
+ +
+
{{jsxref("Statements/with", "with")}} {{deprecated_inline}}
+
拓展一个语句的作用域。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES1', '#sec-12', 'Statements')}}{{Spec2('ES1')}}Initial definition
{{SpecName('ES3', '#sec-12', 'Statements')}}{{Spec2('ES3')}}
{{SpecName('ES5.1', '#sec-12', 'Statements')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-ecmascript-language-statements-and-declarations', 'ECMAScript Language: Statements and Declarations')}}{{Spec2('ES6')}}New: function*, let, for...of, yield, class
{{SpecName('ESDraft', '#sec-ecmascript-language-statements-and-declarations', 'ECMAScript Language: Statements and Declarations')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/label/index.html b/files/zh-cn/web/javascript/reference/statements/label/index.html new file mode 100644 index 0000000000..c0bf3413c7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/label/index.html @@ -0,0 +1,203 @@ +--- +title: label +slug: Web/JavaScript/Reference/Statements/label +tags: + - JavaScript + - Statement + - 语句 +translation_of: Web/JavaScript/Reference/Statements/label +--- +
{{jsSidebar("Statements")}}
+ +

标记语句可以和 {{jsxref("Statements/break", "break")}} 或 {{jsxref("Statements/continue", "continue")}} 语句一起使用。标记就是在一条语句前面加个可以引用的标识符(identifier)。

+ +
  {{EmbedInteractiveExample("pages/js/statement-label.html")}}
+ + + +
+

备注:使用标记的循环或语句块非常罕见。通常情况下,可以使用函数调用而不是(基于标记的)循环跳转。

+
+ +

语法

+ +
label :
+   statement
+
+ +
+
label
+
任何不属于保留关键字的 JavaScript 标识符。
+
statement
+
JavaScript 语句。break 可用于任何标记语句,而 continue 可用于循环标记语句。
+
+ +

描述

+ +

可使用一个标签来唯一标记一个循环,然后使用 break 或 continue 语句来指示程序是否中断循环或继续执行。

+ +

需要注意的是,JavaScript 没有 goto 语句,标记只能和 break 或 continue 一起使用。

+ +

严格模式中,你不能使用 “let” 作为标签名称。它会抛出一个 {{jsxref("SyntaxError")}}(因为 let 是一个保留的标识符)。

+ +

示例

+ +

for 循环中使用带标记的 continue 语句

+ +
    var i, j;
+
+    loop1:
+    for (i = 0; i < 3; i++) {      //The first for statement is labeled "loop1"
+       loop2:
+       for (j = 0; j < 3; j++) {   //The second for statement is labeled "loop2"
+          if (i === 1 && j === 1) {
+             continue loop1;
+          }
+          console.log('i = ' + i + ', j = ' + j);
+       }
+    }
+
+// Output is:
+//   "i = 0, j = 0"
+//   "i = 0, j = 1"
+//   "i = 0, j = 2"
+//   "i = 1, j = 0"
+//   "i = 2, j = 0"
+//   "i = 2, j = 1"
+//   "i = 2, j = 2"
+// Notice how it skips both "i = 1, j = 1" and "i = 1, j = 2"
+
+ +

使用带标记的 continue 语句

+ +

若给定一个数据数组和一个测试数组,则下面的例子会统计通过测试的数据的数量。

+ +
var itemsPassed = 0;
+var i, j;
+
+top:
+for (i = 0; i < items.length; i++) {
+  for (j = 0; j < tests.length; j++) {
+    if (!tests[j].pass(items[i])) {
+      continue top;
+    }
+  }
+
+  itemsPassed++;
+}
+ +

for 循环中使用带标记的 break

+ +
var i, j;
+
+loop1:
+for (i = 0; i < 3; i++) {      //The first for statement is labeled "loop1"
+   loop2:
+   for (j = 0; j < 3; j++) {   //The second for statement is labeled "loop2"
+      if (i == 1 && j == 1) {
+         break loop1;
+      }
+      console.log("i = " + i + ", j = " + j);
+   }
+}
+
+// Output is:
+//   "i = 0, j = 0"
+//   "i = 0, j = 1"
+//   "i = 0, j = 2"
+//   "i = 1, j = 0"
+// Notice the difference with the previous continue example
+ +

使用带标记的 break 语句

+ +

若给定一个数据数组和一个测试数组,则下面的例子会判断是否所有数据均通过了测试。

+ +
var allPass = true;
+var i, j;
+
+top:
+for (i = 0; items.length; i++)
+  for (j = 0; j < tests.length; i++)
+    if (!tests[j].pass(items[i])){
+      allPass = false;
+      break top;
+    }
+ +

在标记块中使用 break

+ +

你可以在代码块中使用标记,但只有 break 语句可以使用非循环标记。

+ +
foo: {
+  console.log('face');
+  break foo;
+  console.log('this will not be executed');
+}
+console.log('swap');
+
+// this will log:
+
+// "face"
+// "swap
+ +

标记函数声明

+ +

从ECMAScript 2015开始,标准的函数声明现在对规范的 Web 兼容性附件中的非严格代码进行了标准化。

+ +
L: function F() {}
+ +

严格模式中,这会抛出 {{jsxref("SyntaxError")}}:

+ +
'use strict';
+L: function F() {}
+// SyntaxError: functions cannot be labelled
+
+ +

无论是否处于严格模式下,生成器函数都不能被标记:

+ +
L: function* F() {}
+// SyntaxError: generator functions cannot be labelled
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2
{{SpecName('ES5.1', '#sec-12.12', 'Labelled statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-labelled-statements', 'Labelled statement')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-labelled-statements', 'Labelled statement')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.label")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/let/index.html b/files/zh-cn/web/javascript/reference/statements/let/index.html new file mode 100644 index 0000000000..84898ef237 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/let/index.html @@ -0,0 +1,279 @@ +--- +title: let +slug: Web/JavaScript/Reference/Statements/let +tags: + - ECMAScript 2015 + - ECMAScript6 + - JavaScript + - let + - 变量 + - 变量声明 + - 声明 +translation_of: Web/JavaScript/Reference/Statements/let +--- +
{{jsSidebar("Statements")}}
+ +
+ +
let 语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
+ +
{{EmbedInteractiveExample("pages/js/statement-let.html")}}
+ + + +

语法

+ +
let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
+ +

参数

+ +
+
var1, var2, …, varN
+
变量名。必须是合法的标识符。
+
value1, value2, …, valueN 
+
变量的初始值。可以是任意合法的表达式。
+
+ +

描述

+ +

let允许你声明一个作用域被限制在 {{jsxref("statements/block", "块")}}级中的变量、语句或者表达式。与 {{jsxref("statements/var", "var")}} 关键字不同的是, {{jsxref("statements/var", "var")}}声明的变量只能是全局或者整个函数块的。 {{jsxref("statements/var", "var")}} 和 let 的不同之处在于后者是在编译时才初始化(见下面)。

+ +

就像{{jsxref("statements/const", "const", "Description")}} 一样,let不会在全局声明时(在最顶部的范围)创建{{domxref('window')}} 对象的属性。

+ +

可以从这里了解我们为什么使用“let”。

+ +

作用域规则

+ +

let声明的变量只在其声明的块或子块中可用,这一点,与var相似。二者之间最主要的区别在于var声明的变量的作用域是整个封闭函数。

+ +
function varTest() {
+  var x = 1;
+  {
+    var x = 2;  // 同样的变量!
+    console.log(x);  // 2
+  }
+  console.log(x);  // 2
+}
+
+function letTest() {
+  let x = 1;
+  {
+    let x = 2;  // 不同的变量
+    console.log(x);  // 2
+  }
+  console.log(x);  // 1
+}
+
+ +

在程序和方法的最顶端,let不像 var 一样,let不会在全局对象里新建一个属性。比如:

+ +

位于函数或代码顶部的var声明会给全局对象新增属性, 而let不会。例如:

+ +
var x = 'global';
+let y = 'global';
+console.log(this.x); // "global"
+console.log(this.y); // undefined
+
+ +

模仿私有成员

+ +

在处理构造函数的时候,可以通过let声明而不是闭包来创建一个或多个私有成员。

+ +
var Thing;
+
+{
+  let privateScope = new WeakMap();
+  let counter = 0;
+
+  Thing = function() {
+    this.someProperty = 'foo';
+
+    privateScope.set(this, {
+      hidden: ++counter,
+    });
+  };
+
+  Thing.prototype.showPublic = function() {
+    return this.someProperty;
+  };
+
+  Thing.prototype.showPrivate = function() {
+    return privateScope.get(this).hidden;
+  };
+}
+
+console.log(typeof privateScope);
+// "undefined"
+
+var thing = new Thing();
+
+console.log(thing);
+// Thing {someProperty: "foo"}
+
+thing.showPublic();
+// "foo"
+
+thing.showPrivate();
+// 1
+ +

可以使用var创建和闭包具有相同隐私模式的局部变量,但是它们需要函数作用域(通常是模块模式中的IIFE),而不仅仅是上面示例中的块作用域。

+ +

重复声明

+ +

在同一个函数或块作用域中重复声明同一个变量会引起{{jsxref("SyntaxError")}}。

+ +
if (x) {
+  let foo;
+  let foo; // SyntaxError thrown.
+}
+
+ +

switch 语句中只有一个块,你可能因此而遇到错误。

+ +
let x = 1;
+switch(x) {
+  case 0:
+    let foo;
+    break;
+
+  case 1:
+    let foo; // SyntaxError for redeclaration.
+    break;
+}
+
+ +

然而,需要特别指出的是,一个嵌套在 case 子句中的块会创建一个新的块作用域的词法环境,就不会产生上诉重复声明的错误。

+ +
let x = 1;
+
+switch(x) {
+  case 0: {
+    let foo;
+    break;
+  }
+  case 1: {
+    let foo;
+    break;
+  }
+}
+
+ +

暂存死区

+ +

与通过  var 声明的有初始化值 undefined 的变量不同,通过 let 声明的变量直到它们的定义被执行时才初始化。在变量初始化前访问该变量会导致 ReferenceError。该变量处在一个自块顶部到初始化处理的“暂存死区”中。

+ +
function do_something() {
+  console.log(bar); // undefined
+  console.log(foo); // ReferenceError
+  var bar = 1;
+  let foo = 2;
+}
+ +

暂存死区与 typeof

+ +

与通过var声明的变量, 有初始化值 undefined和只是未声明的变量不同的是,如果使用typeof检测在暂存死区中的变量, 会抛出ReferenceError异常:

+ +
// prints out 'undefined'
+console.log(typeof undeclaredVariable);
+
+// results in a 'ReferenceError'
+console.log(typeof i);
+let i = 10;
+
+ +

暂存死区和静态作用域/词法作用域的相关例子

+ +

由于词法作用域,表达式(foo + 55)内的标识符foo被认为是if块的foo变量,而不是值为33的块外面的变量foo。

+ +

在同一行,这个if块中的foo已经在词法环境中被创建了,但是还没有到达(或者终止)它的初始化(这是语句本身的一部分)。

+ +

这个if块里的foo还依旧在暂存死区里。

+ +
function test(){
+   var foo = 33;
+   if (foo) {
+      let foo = (foo + 55); // ReferenceError
+   }
+}
+test();
+ +

在以下情况下,这种现象可能会使您感到困惑。 let n of n.a已经在for循环块的私有范围内。因此,标识符n.a被解析为位于指令本身("let n")中的“ n”对象的属性“ a”。

+ +

在没有执行到它的初始化语句之前,它仍旧存在于暂存死区中。

+ +
function go(n) {
+  // n here is defined!
+  console.log(n); // Object {a: [1,2,3]}
+
+  for (let n of n.a) { // ReferenceError
+    console.log(n);
+  }
+}
+
+go({a: [1, 2, 3]});
+ +

其他情况

+ +

用在块级作用域中时, let将变量的作用域限制在块内, 而var声明的变量的作用域是在函数内.

+ +
var a = 1;
+var b = 2;
+
+if (a === 1) {
+  var a = 11; // the scope is global
+  let b = 22; // the scope is inside the if-block
+
+  console.log(a);  // 11
+  console.log(b);  // 22
+}
+
+console.log(a); // 11
+console.log(b); // 2
+ +

而这种var 与 let合并的声明方式会报SyntaxError错误, 因为var会将变量提升至块的顶部, 这会导致隐式地重复声明变量.

+ +
let x = 1;
+
+{
+  var x = 2; // SyntaxError for re-declaration
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-let-and-const-declarations', 'Let and Const Declarations')}}{{Spec2('ES6')}}Initial definition. Does not specify let expressions or let blocks.
{{SpecName('ESDraft', '#sec-let-and-const-declarations', 'Let and Const Declarations')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.let")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/return/index.html b/files/zh-cn/web/javascript/reference/statements/return/index.html new file mode 100644 index 0000000000..a8ae7459e0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/return/index.html @@ -0,0 +1,149 @@ +--- +title: return +slug: Web/JavaScript/Reference/Statements/return +tags: + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/return +--- +
+
{{jsSidebar("Statements")}}
+
+ +

return语句终止函数的执行,并返回一个指定的值给函数调用者。

+ +

语法

+ +
return [[expression]]; 
+ +
+
expression
+
表达式的值会被返回。如果忽略,则返回 undefined
+
+ +

描述

+ +

当在函数体中使用return语句时,函数将会停止执行。如果指定一个值,则这个值返回给函数调用者。例如,以下函数返回其参数x的平方,其中x是数字。

+ +
function square(x) {
+   return x * x;
+}
+var demo = square(3);
+// demo will equal 9
+ +

如果省略该值,则返回undefined

+ +

下面的 return 语句都会终止函数的执行:

+ +
return;
+return true;
+return false;
+return x;
+return x + y / 3;
+
+ +

自动插入分号

+ +

自动插入分号(ASI) 规则会影响 return 语句。在 return 关键字和被返回的表达式之间不允许使用行终止符。

+ +
return
+a + b;
+ +

根据 ASI,被转换为:

+ +
return;
+a + b;
+ +

控制台会警告“unreachable code after return statement”。

+ +
+

从 Gecko 40 {{geckoRelease(40)}}开始,如果在一个 return 语句后发现无法访问的代码,控制台将会显示一个警告。

+
+ +

示例

+ +

中断一个函数的执行

+ +

函数将会在return语句执行后立即中止。

+ +
function counter() {
+  for (var count = 1; ; count++) {  // 无限循环
+    console.log(count + "A"); // 执行5次
+      if (count === 5) {
+        return;
+      }
+      console.log(count + "B");  // 执行4次
+    }
+  console.log(count + "C");  // 永远不会执行
+}
+
+counter();
+
+// Output:
+// 1A
+// 1B
+// 2A
+// 2B
+// 3A
+// 3B
+// 4A
+// 4B
+// 5A
+
+ +

返回一个函数

+ +

另见关于闭包的文章。

+ +
function magic(x) {
+  return function calc(x) { return x * 42};
+}
+
+var answer = magic();
+answer(1337); // 56154
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-12.9', 'Return statement')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-return-statement', 'Return statement')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-return-statement', 'Return statement')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.return")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/switch/index.html b/files/zh-cn/web/javascript/reference/statements/switch/index.html new file mode 100644 index 0000000000..64cce4f231 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/switch/index.html @@ -0,0 +1,308 @@ +--- +title: switch +slug: Web/JavaScript/Reference/Statements/switch +tags: + - JavaScript + - Reference + - Statement + - Web + - 参考 + - 声明 +translation_of: Web/JavaScript/Reference/Statements/switch +--- +
{{jsSidebar("Statements")}}
+ +

switch 语句评估一个表达式,将表达式的值与case子句匹配,并执行与该情况相关联的语句

+ +
{{EmbedInteractiveExample("pages/js/statement-switch.html")}}
+ + + +

语法

+ +
switch (expression) {
+  case value1:
+    // 当 expression 的结果与 value1 匹配时,执行此处语句
+    [break;]
+  case value2:
+    // 当 expression 的结果与 value2 匹配时,执行此处语句
+    [break;]
+  ...
+  case valueN:
+    // 当 expression 的结果与 valueN 匹配时,执行此处语句
+    [break;]
+  [default:
+    // 如果 expression 与上面的 value 值都不匹配,执行此处语句
+    [break;]]
+}
+ +
+
expression
+
一个用来与 case 子语句匹配的表达式。
+
case valueN {{optional_inline}}
+
用于匹配 expressioncase 子句。如果 expression 与给定的 valueN 相匹配,则执行该 case 子句中的语句直到该 switch 语句结束或遇到一个 break
+
default {{optional_inline}}
+
一个 default 子句;如果给定,这条子句会在 expression 的值与任一 case 语句均不匹配时执行。
+
+ +

描述

+ +

一个 switch 语句首先会计算其 expression 。然后,它将从第一个 case 子句开始直到寻找到一个其表达式值与所输入的 expression 的值所相等的子句(使用 严格运算符===)并将控制权转给该子句,执行相关语句。(如果多个 case 与提供的值匹配,则选择匹配的第一个 case,即使这些 case 彼此间并不相等。)

+ +

如果没有 case 子句相匹配,程序则会寻找那个可选的 default 子句,如果找到了,将控制权交给它,执行相关语句。若没有 default 子句,程序将继续执行直到 switch 结束。按照惯例,default 子句是最后一个子句,不过也不需要这样做。

+ +

可选的 break 语句确保程序立即从相关的 case 子句中跳出 switch 并接着执行 switch 之后的语句。若 break 被省略,程序会继续执行 switch 语句中的下一条语句。

+ +

示例

+ +

使用 switch

+ +

下面的例子中,如果 expr 计算为 "Bananas",程序就会匹配值为 "Bananas" 的 case 然后执行相关语句。当遇到 break 时,程序就跳出 switch 然后执行 switch 后的语句。若 break 被省略,值为 "Cherries" 的 case 中的语句就也将被执行。

+ +
switch (expr) {
+  case 'Oranges':
+    console.log('Oranges are $0.59 a pound.');
+    break;
+  case 'Apples':
+    console.log('Apples are $0.32 a pound.');
+    break;
+  case 'Bananas':
+    console.log('Bananas are $0.48 a pound.');
+    break;
+  case 'Cherries':
+    console.log('Cherries are $3.00 a pound.');
+    break;
+  case 'Mangoes':
+  case 'Papayas':
+    console.log('Mangoes and papayas are $2.79 a pound.');
+    break;
+  default:
+    console.log('Sorry, we are out of ' + expr + '.');
+}
+
+console.log("Is there anything else you'd like?");
+
+ +

如果忘记 break 会怎么样?

+ +

如果你忘记添加 break,那么代码将会从值所匹配的 case 语句开始运行,然后持续执行下一个 case 语句而不论值是否匹配。例子如下:

+ +
var foo = 0;
+switch (foo) {
+  case -1:
+    console.log('negative 1');
+    break;
+  case 0: // foo 的值为 0 所以匹配这里所以这一块会运行
+    console.log(0);
+    // 注意:那个没写的 break 原本在这儿
+  case 1: // 'case 0:' 里没有 break 语句所以这个 case 也会运行
+    console.log(1);
+    break; // 遇到了 break,所以不会再继续进入 'case 2:' 了
+  case 2:
+    console.log(2);
+    break;
+  default:
+    console.log('default');
+}
+ +

我能把 default 放到 case 之间吗?

+ +

可以啊!JavaScript 会在它找不到匹配项时跳回到那个 default :

+ +
var foo = 5;
+switch (foo) {
+  case 2:
+    console.log(2);
+    break; // 遇到 break,所以不会继续进入 'default:'
+  default:
+    console.log('default')
+    // 掉到下面
+  case 1:
+    console.log('1');
+}
+
+ +

即使你把 default 放到其它 case 之上,它仍有效。

+ +

使用多准则 case 的方法

+ +

这个技术来源于此:

+ +

Switch statement multiple cases in JavaScript (Stack Overflow)

+ +

多 case - 单一操作

+ +

这种方法利用这样一个事实:如果 case 语句之下没有 break ,它将继续执行下一个 case 语句,而不管 case 是否符合条件。 请看“如果忘记 break 会怎么样?”部分。

+ +

这是一个单操作顺序的 switch 语句,其中四个不同值的执行结果完全一样。

+ +
var Animal = 'Giraffe';
+switch (Animal) {
+  case 'Cow':
+  case 'Giraffe':
+  case 'Dog':
+  case 'Pig':
+    console.log('This animal will go on Noah\'s Ark.');
+    break;
+  case 'Dinosaur':
+  default:
+    console.log('This animal will not.');
+}
+ +

多 case - 关联操作

+ +

这是一个关联操作顺序的 switch 语句,其中,根据所输入的整数,你会得到不同的输出。这表示它将以你放置 case 语句的顺序遍历,并且不必是数字顺序的。在 JavaScript 中,你甚至可以将字符串定义到这些 case 语句里。

+ +
var foo = 1;
+var output = 'Output: ';
+switch (foo) {
+  case 0:
+    output += 'So ';
+  case 1:
+    output += 'What ';
+    output += 'Is ';
+  case 2:
+    output += 'Your ';
+  case 3:
+    output += 'Name';
+  case 4:
+    output += '?';
+    console.log(output);
+    break;
+  case 5:
+    output += '!';
+    console.log(output);
+    break;
+  default:
+    console.log('Please pick a number from 0 to 5!');
+}
+ +

这个例子的输出:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueLog text
foo is NaN or not 1, 2, 3, 4, 5 or 0Please pick a number from 0 to 5!
0Output: So What Is Your Name?
1Output: What Is Your Name?
2Output: Your Name?
3Output: Name?
4Output: ?
5Output: !
+ +

switch 语句内的块级作用域

+ +

随着绝大多数现代浏览器已支持 ECMAScript 2015 (ES6),在某些场景下您可能需要使用 letconst 语句,以在块级作用域内声明变量。

+ +

以这段代码为例:

+ +
const action = 'say_hello';
+switch (action) {
+  case 'say_hello':
+    let message = 'hello';
+           console.log('0 ~5');
+           break;
+  case 'say_hi':
+    let message = 'hi';
+    case 6: console.log('6');
+    break;
+  default:
+    console.log('Empty action received.');
+    break;
+}
+ +

这个示例会导致意想不到的错误 Uncaught SyntaxError: Identifier 'message' has already been declared.

+ +

这是因为第一个 let message = 'hello'; 与第二个 let message = 'hi'; 语句产生了冲突,虽然他们处于各自分隔的 case 语句中,即 case 'say_hello': 和 case 'say_hi':。导致这一问题的根本原因在于两个 let 语句处于同一个块级作用域,所以它们被认为是同一个变量名的重复声明。

+ +

通过把 case 语句包装到括号里面,我们就可以轻松解决这个问题。

+ +
const action = 'say_hello';
+switch (action) {
+  case 'say_hello': { // added brackets
+    let message = 'hello';
+    console.log(message);
+    break;
+  } // added brackets
+  case 'say_hi': { // added brackets
+    let message = 'hi';
+    console.log(message);
+    break;
+  } // added brackets
+  default: { // added brackets
+    console.log('Empty action received.');
+    break;
+  } // added brackets
+}
+ +

此时,这段代码就会在控制台输出 hello,不会再有任何报错。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.2
{{SpecName('ES5.1', '#sec-12.11', 'switch statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-switch-statement', 'switch statement')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-switch-statement', 'switch statement')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.switch")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/throw/index.html b/files/zh-cn/web/javascript/reference/statements/throw/index.html new file mode 100644 index 0000000000..aee6a02e79 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/throw/index.html @@ -0,0 +1,195 @@ +--- +title: throw +slug: Web/JavaScript/Reference/Statements/throw +tags: + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/throw +--- +
{{jsSidebar("Statements")}}
+ +

throw语句用来抛出一个用户自定义的异常。当前函数的执行将被停止(throw之后的语句将不会执行),并且控制将被传递到调用堆栈中的第一个catch块。如果调用者函数中没有catch块,程序将会终止。

+ +

{{EmbedInteractiveExample("pages/js/statement-throw.html")}}

+ + + +

语法

+ +
throw expression; 
+ +
+
expression
+
要抛出的表达式。
+
+ +

描述

+ +

使用throw语句来抛出一个异常。当你抛出异常时,expression 指定了异常的内容。下面的每行都抛出了一个异常:

+ +
throw "Error2"; // 抛出了一个值为字符串的异常
+throw 42;       // 抛出了一个值为整数42的异常
+throw true;     // 抛出了一个值为true的异常
+ +

注意throw语句同样受到自动分号插入(ASI)机制的控制,在throw关键字和值之间不允许有行终止符。

+ +

示例

+ +

抛出一个对象

+ +

你可以在抛出异常时指定一个对象。然后可以在catch块中引用对象的属性。以下示例创建一个类型为UserException的对象,并在throw语句中使用它。

+ +
function UserException(message) {
+   this.message = message;
+   this.name = "UserException";
+}
+function getMonthName(mo) {
+   mo = mo-1; // 调整月份数字到数组索引 (1=Jan, 12=Dec)
+   var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
+      "Aug", "Sep", "Oct", "Nov", "Dec"];
+   if (months[mo] !== undefined) {
+      return months[mo];
+   } else {
+      throw new UserException("InvalidMonthNo");
+   }
+}
+
+try {
+   // statements to try
+   var myMonth = 15; // 15 超出边界并引发异常
+   var monthName = getMonthName(myMonth);
+} catch (e) {
+   var monthName = "unknown";
+   console.log(e.message, e.name); // 传递异常对象到错误处理
+}
+
+ +

另一个抛出异常对象的示例

+ +

下面的示例中测试一个字符串是否是美国邮政编码。如果邮政编码是无效的,那么throw语句将会抛出一个类型为 ZipCodeFormatException的异常对象实例。

+ +
/*
+ * 创建 ZipCode 示例.
+ *
+ * 可被接受的邮政编码格式:
+ *    12345
+ *    12345-6789
+ *    123456789
+ *    12345 6789
+ *
+ * 如果构造函数参数传入的格式不符合以上任何一个格式,将会抛出异常。
+ */
+
+function ZipCode(zip) {
+   zip = new String(zip);
+   pattern = /[0-9]{5}([- ]?[0-9]{4})?/;
+   if (pattern.test(zip)) {
+      // zip code value will be the first match in the string
+      this.value = zip.match(pattern)[0];
+      this.valueOf = function() {
+         return this.value
+      };
+      this.toString = function() {
+         return String(this.value)
+      };
+   } else {
+      throw new ZipCodeFormatException(zip);
+   }
+}
+
+function ZipCodeFormatException(value) {
+   this.value = value;
+   this.message = "不是正确的邮政编码";
+   this.toString = function() {
+      return this.value + this.message
+   };
+}
+
+/*
+ * 这可能是一个验证美国地区中的脚本
+ */
+
+const ZIPCODE_INVALID = -1;
+const ZIPCODE_UNKNOWN_ERROR = -2;
+
+function verifyZipCode(z) {
+   try {
+      z = new ZipCode(z);
+   } catch (e) {
+      if (e instanceof ZipCodeFormatException) {
+         return ZIPCODE_INVALID;
+      } else {
+         return ZIPCODE_UNKNOWN_ERROR;
+      }
+   }
+   return z;
+}
+
+a = verifyZipCode(95060);         // 返回 95060
+b = verifyZipCode(9560);          // 返回 -1
+c = verifyZipCode("a");           // 返回 -1
+d = verifyZipCode("95060");       // 返回 95060
+e = verifyZipCode("95060 1234");  // 返回 95060 1234
+
+ +

重新抛出异常

+ +

你可以使用throw来抛出异常。下面的例子捕捉了一个异常值为数字的异常,并在其值大于50后重新抛出异常。重新抛出的异常传播到闭包函数或顶层,以便用户看到它。

+ +
try {
+   throw n; // 抛出一个数值异常
+} catch (e) {
+   if (e <= 50) {
+      // 异常在 1-50 之间时,直接处理
+   } else {
+      // 异常无法处理,重新抛出
+      throw e;
+   }
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.4
{{SpecName('ES5.1', '#sec-12.13', 'throw statement')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-throw-statement', 'throw statement')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-throw-statement', 'throw statement')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.throw")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/try...catch/index.html b/files/zh-cn/web/javascript/reference/statements/try...catch/index.html new file mode 100644 index 0000000000..ff290ab4ba --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/try...catch/index.html @@ -0,0 +1,302 @@ +--- +title: try...catch +slug: Web/JavaScript/Reference/Statements/try...catch +tags: + - Error + - Exception + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/try...catch +--- +
{{jsSidebar("Statements")}}
+ +

try...catch语句标记要尝试的语句块,并指定一个出现异常时抛出的响应。

+ +

{{EmbedInteractiveExample("pages/js/statement-trycatch.html")}}

+ +

语法

+ +
try {
+   try_statements
+}
+[catch (exception_var_1 if condition_1) { // non-standard
+   catch_statements_1
+}]
+...
+[catch (exception_var_2) {
+   catch_statements_2
+}]
+[finally {
+   finally_statements
+}]
+
+ +
+
try_statements
+
需要被执行的语句。
+
+ +
+
catch_statements_1, catch_statements_2
+
如果在try块里有异常被抛出时执行的语句。
+
+ +
+
exception_var_1, exception_var_2
+
用于保存关联catch子句的异常对象的标识符。
+
+ +
+
condition_1
+
一个条件表达式。
+
+ +
+
finally_statements
+
try语句块之后执行的语句块。无论是否有异常抛出或捕获这些语句都将执行。
+
+ +

描述

+ +

try语句包含了由一个或者多个语句组成的try块, 和至少一个catch块或者一个finally块的其中一个,或者两个兼有, 下面是三种形式的try声明:

+ +
    +
  1. try...catch
  2. +
  3. try...finally
  4. +
  5. try...catch...finally
  6. +
+ +

catch子句包含try块中抛出异常时要执行的语句。也就是,你想让try语句中的内容成功, 如果没成功,你想控制接下来发生的事情,这时你可以在catch语句中实现。 如果在try块中有任何一个语句(或者从try块中调用的函数)抛出异常,控制立即转向catch子句。如果在try块中没有异常抛出,会跳过catch子句。

+ +

finally子句在try块和catch块之后执行但是在下一个try声明之前执行。无论是否有异常抛出或捕获它总是执行。

+ +

你可以嵌套一个或者更多的try语句。如果内部的try语句没有catch子句,那么将会进入包裹它的try语句的catch子句。

+ +

你也可以用try语句去处理 JavaScript 异常。参考JavaScript 指南了解更多关于 Javascript 异常的信息。

+ +

无条件的catch

+ +

当使用单个无条件catch子句时,抛出的任何异常时都会进入到catch块。例如,当在下面的代码中发生异常时,控制转移到catch子句。

+ +
try {
+   throw "myException"; // generates an exception
+}
+catch (e) {
+   // statements to handle any exceptions
+   logMyErrors(e); // pass exception object to error handler
+}
+
+ +

catch块指定一个标识符(在上面的示例中为e),该标识符保存由throw语句指定的值。catch块是唯一的,因为当输入catch块时,JavaScript 会创建此标识符,并将其添加到当前作用域;标识符仅在catch块执行时存在;catch块执行完成后,标识符不再可用。

+ +

条件catch

+ +

{{non-standard_header}}

+ +

你也可以用一个或者更多条件catch子句来处理特定的异常。在这种情况下,当异常抛出时将会进入合适的catch子句中。在下面的代码中,try块的代码可能会抛出三种异常:{{jsxref("TypeError")}},{{jsxref("RangeError")}}和{{jsxref("EvalError")}}。当一个异常抛出时,控制将会进入与其对应的catch语句。如果这个异常不是特定的,那么控制将转移到无条件catch子句。

+ +

当用一个无条件catch子句和一个或多个条件语句时,无条件catch子句必须放在最后。否则当到达条件语句之前所有的异常将会被非条件语句拦截。

+ +

提醒:这个功能不符合 ECMAscript 规范。

+ +
try {
+    myroutine(); // may throw three types of exceptions
+} catch (e if e instanceof TypeError) {
+    // statements to handle TypeError exceptions
+} catch (e if e instanceof RangeError) {
+    // statements to handle RangeError exceptions
+} catch (e if e instanceof EvalError) {
+    // statements to handle EvalError exceptions
+} catch (e) {
+    // statements to handle any unspecified exceptions
+    logMyErrors(e); // pass exception object to error handler
+}
+
+ +

下面用符合 ECMAscript 规范的简单的 JavaScript 来编写相同的“条件catch子句”(显然更加冗长的,但是可以在任何地方运行):

+ +
try {
+  myRoutine();
+} catch (e) {
+  if (e instanceof RangeError) {
+    // statements to handle this very common expected error
+  } else {
+    throw e;  // re-throw the error unchanged
+  }
+}
+ +

异常标识符

+ +

try块中的抛出一个异常时, exception_var(如catch (e)中的e)用来保存被抛出声明指定的值。你可以用这个标识符来获取关于被抛出异常的信息。

+ +

这个标识符是catch子语句内部的。换言之,当进入catch子语句时标识符创建,catch子语句执行完毕后,这个标识符将不再可用。

+ +
function isValidJSON(text) {
+  try {
+    JSON.parse(text);
+    return true;
+  } catch {
+    return false;
+  }
+}
+ +

finally

+ +

finally块包含的语句在try块和catch之后,try..catch..finally块后的语句之前执行。请注意,无论是否抛出异常finally子句都会执行。此外,如果抛出异常,即使没有catch子句处理异常,finally子句中的语句也会执行。

+ +

以下示例打开一个文件,然后执行使用该文件的语句(服务器端 JavaScript 允许您访问文件)。如果文件打开时抛出异常,则finally子句会在脚本失败之前关闭该文件。finally中的代码最终也会在trycatch block显式返回时执行。

+ +
openMyFile()
+try {
+   // tie up a resource
+   writeMyFile(theData);
+}
+finally {
+   closeMyFile(); // always close the resource
+}
+
+ +

示例

+ +

嵌套 try 块

+ +

首先让我们看看这里发生什么:

+ +
try {
+  try {
+    throw new Error("oops");
+  }
+  finally {
+    console.log("finally");
+  }
+}
+catch (ex) {
+  console.error("outer", ex.message);
+}
+
+// Output:
+// "finally"
+// "outer" "oops"
+
+ +

现在,如果我们已经在 try 语句中,通过增加一个 catch 语句块捕获了异常

+ +
try {
+  try {
+    throw new Error("oops");
+  }
+  catch (ex) {
+    console.error("inner", ex.message);
+  }
+  finally {
+    console.log("finally");
+  }
+}
+catch (ex) {
+  console.error("outer", ex.message);
+}
+
+// Output:
+// "inner" "oops"
+// "finally"
+
+ +

现在,让我们再次抛出错误。

+ +
try {
+  try {
+    throw new Error("oops");
+  }
+  catch (ex) {
+    console.error("inner", ex.message);
+    throw ex;
+  }
+  finally {
+    console.log("finally");
+  }
+}
+catch (ex) {
+  console.error("outer", ex.message);
+}
+
+// Output:
+// "inner" "oops"
+// "finally"
+// "outer" "oops"
+
+ +

任何给定的异常只会被离它最近的封闭 catch 块捕获一次。当然,在“inner”块抛出的任何新异常 (因为 catch 块里的代码也可以抛出异常),将会被“outer”块所捕获。

+ +

从 finally 语句块返回

+ +

如果从finally块中返回一个值,那么这个值将会成为整个try-catch-finally的返回值,无论是否有return语句在trycatch中。这包括在catch块里抛出的异常。

+ +
try {
+  try {
+    throw new Error("oops");
+  }
+  catch (ex) {
+    console.error("inner", ex.message);
+    throw ex;
+  }
+  finally {
+    console.log("finally");
+    return;
+  }
+}
+catch (ex) {
+  console.error("outer", ex.message);
+}
+
+// 注: 此 try catch 语句需要在 function 中运行才能作为函数的返回值, 否则直接运行会报语法错误
+// Output:
+// "inner" "oops"
+// "finally"
+
+ +

因为 finally 块里的 return 语句,"oops" 没有抛出到外层,从 catch 块返回的值同样适用。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.4
{{SpecName('ES5.1', '#sec-12.14', 'try statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-try-statement', 'try statement')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-try-statement', 'try statement')}}{{Spec2('ESDraft')}}Not part of the current ECMA-262 standard: Multiple catch clauses and conditional clauses (SpiderMonkey extension, JavaScript 1.5).
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.try_catch")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/var/index.html b/files/zh-cn/web/javascript/reference/statements/var/index.html new file mode 100644 index 0000000000..8e28dc4d17 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/var/index.html @@ -0,0 +1,216 @@ +--- +title: var 描述 +slug: Web/JavaScript/Reference/Statements/var +tags: + - JavaScript + - Statement + - 声明 +translation_of: Web/JavaScript/Reference/Statements/var +--- +
{{jsSidebar("Statements")}}
+ +

var 声明语句声明一个变量,并可选地将其初始化为一个值。

+ +

{{EmbedInteractiveExample("pages/js/statement-var.html")}}

+ + + +

语法

+ +
var varname1 [= value1] [, varname2 [= value2] ... [, varnameN [= valueN]]];
+ +
+
varnameN
+
变量名。变量名可以定义为任何合法标识符。
+
+ +
+
valueN
+
变量的初始化值。该值可以是任何合法的表达式。默认值为 undefined
+
+ +

描述

+ +

变量声明,无论发生在何处,都在执行任何代码之前进行处理。用 var 声明的变量的作用域是它当前的执行上下文,它可以是嵌套的函数,或者对于声明在任何函数外的变量来说是全局。如果你重新声明一个 JavaScript 变量,它将不会丢失其值。

+ +

当赋值给未声明的变量, 则执行赋值后, 该变量会被隐式地创建为全局变量(它将成为全局对象的属性)。

+ +

声明和未声明变量之间的差异是:

+ +

1. 声明变量的作用域限制在其声明位置的上下文中,而非声明变量总是全局的。

+ +
function x() {
+  y = 1;   // 在严格模式(strict mode)下会抛出 ReferenceError 异常
+  var z = 2;
+}
+
+x();
+
+console.log(y); // 打印 "1"
+console.log(z); // 抛出 ReferenceError: z 未在 x 外部声明
+
+ +

2. 声明变量在任何代码执行前创建,而非声明变量只有在执行赋值操作的时候才会被创建。

+ +
console.log(a);                // 抛出ReferenceError。
+console.log('still going...'); // 打印"still going..."。
+ +
var a;
+console.log(a);                // 打印"undefined"或""(不同浏览器实现不同)。
+console.log('still going...'); // 打印"still going..."。
+ +

3. 声明变量是它所在上下文环境的不可配置属性,非声明变量是可配置的(如非声明变量可以被删除)。

+ +
var a = 1;
+b = 2;
+
+delete this.a; // 在严格模式(strict mode)下抛出TypeError,其他情况下执行失败并无任何提示。
+delete this.b;
+
+console.log(a, b); // 抛出ReferenceError。
+// 'b'属性已经被删除。
+
+ +

由于这三个差异,未能声明变量将很可能导致意想不到的结果。因此,建议始终声明变量,无论它们是在函数还是全局作用域内。 而且,在 ECMAScript 5 严格模式下,分配给未声明的变量会引发错误。

+ +

变量提升

+ +

由于变量声明(以及其他声明)总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明。这意味着变量可以在声明之前使用,这个行为叫做“hoisting”。“hoisting”就像是把所有的变量声明移动到函数或者全局代码的开头位置。

+ +
bla = 2
+var bla;
+// ...
+
+// 可以隐式地(implicitly)将以上代码理解为:
+
+var bla;
+bla = 2;
+
+ +

因此,建议始终在作用域顶部声明变量(全局代码的顶部和函数代码的顶部),这可以清楚知道哪些变量是函数作用域(本地),哪些变量在作用域链上解决。

+ +

重要的是,提升将影响变量声明,而不会影响其值的初始化。当到达赋值语句时,该值将确实被分配:

+ +
function do_something() {
+  console.log(bar); // undefined
+  var bar = 111;
+  console.log(bar); // 111
+}
+
+// is implicitly understood as:
+function do_something() {
+  var bar;
+  console.log(bar); // undefined
+  bar = 111;
+  console.log(bar); // 111
+}
+ +

例子

+ +

声明并初始化两个变量:

+ +
var a = 0, b = 0;
+
+ +

给两个变量赋值成字符串值:

+ +
var a = "A";
+var b = a;
+
+// 等效于:
+
+var a, b = a = "A";
+
+ +

留意其中的顺序:

+ +
var x = y, y = 'A';
+console.log(x + y); // undefinedA
+
+ +

在这里,xy 在代码执行前就已经创建了,而赋值操作发生在创建之后。当"x = y"执行时,y 已经存在,所以不抛出ReferenceError,并且它的值是'undefined'。所以 x 被赋予 undefined 值。然后,y 被赋予'A'。于是,在执行完第一行之后,x === undefined && y === 'A' 才出现了这样的结果。

+ +

多个变量的初始化

+ +
var x = 0;
+
+function f(){
+  var x = y = 1; // x在函数内部声明,y不是!
+}
+f();
+
+console.log(x, y); // 0, 1
+// x 是全局变量。
+// y 是隐式声明的全局变量。 
+ +

隐式全局变量和外部函数作用域

+ +

看起来像是隐式全局作用域的变量也有可能是其外部函数变量的引用。

+ +
var x = 0;  // x是全局变量,并且赋值为0。
+
+console.log(typeof z); // undefined,因为z还不存在。
+
+function a() { // 当a被调用时,
+  var y = 2;   // y被声明成函数a作用域的变量,然后赋值成2。
+
+  console.log(x, y);   // 0 2
+
+  function b() {       // 当b被调用时,
+    x = 3;  // 全局变量x被赋值为3,不生成全局变量。
+    y = 4;  // 已存在的外部函数的y变量被赋值为4,不生成新的全局变量。
+    z = 5;  // 创建新的全局变量z,并且给z赋值为5。
+  }         // (在严格模式下(strict mode)抛出ReferenceError)
+
+  b();     // 调用b时创建了全局变量z。
+  console.log(x, y, z);  // 3 4 5
+}
+
+a();                   // 调用a时同时调用了b。
+console.log(x, z);     // 3 5
+console.log(typeof y); // undefined,因为y是a函数的本地(local)变量。
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0
{{SpecName('ES5.1', '#sec-12.2', 'var statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-variable-statement', 'variable statement')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-variable-statement', 'variable statement')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.var")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/while/index.html b/files/zh-cn/web/javascript/reference/statements/while/index.html new file mode 100644 index 0000000000..2faf378422 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/while/index.html @@ -0,0 +1,101 @@ +--- +title: while +slug: Web/JavaScript/Reference/Statements/while +tags: + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/while +--- +
{{jsSidebar("Statements")}}
+ +

while 语句可以在某个条件表达式为真的前提下,循环执行指定的一段代码,直到那个表达式不为真时结束循环。

+ +
{{EmbedInteractiveExample("pages/js/statement-while.html")}}
+ + + +

语法

+ +
while (condition)
+  statement
+
+ +
+
condition
+
条件表达式,在每次循环前被求值。如果求值为真,statement就会被执行。如果求值为假,则跳出while循环执行后面的语句。
+
statement
+
只要条件表达式求值为真,该语句就会一直被执行。要在循环中执行多条语句,可以使用块语句({ ... })包住多条语句。
+
注意:使用break语句在condition计算结果为真之前停止循环。
+
+ +

示例

+ +

下面的 while 循环会一直循环若干次,直到 n 等于 3

+ +
var n = 0;
+var x = 0;
+
+while (n < 3) {
+  n++;
+  x += n;
+}
+ +

在每次循环中,n 都会自增 1,然后再把 n 加到 x 上。因此,在每轮循环结束后,xn 的值分别是:

+ + + +

当完成第三轮循环后,条件表达式n< 3 不再为真,因此循环终止。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-while-statement', 'while statement')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-while-statement', 'while statement')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-12.6.2', 'while statement')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-12.6.2', 'while statement')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-12.6.1', 'while statement')}}{{Spec2('ES1')}}Initial definition
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.statements.while")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/statements/with/index.html b/files/zh-cn/web/javascript/reference/statements/with/index.html new file mode 100644 index 0000000000..3244d9f28d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/with/index.html @@ -0,0 +1,131 @@ +--- +title: with +slug: Web/JavaScript/Reference/Statements/with +tags: + - Deprecated + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/with +--- +
不建议使用with语句,因为它可能是混淆错误和兼容性问题的根源。有关详细信息,请参阅下面“描述”一节中的“语意不明的弊端”部分。
+ +
{{jsSidebar("Statements")}}
+ +
with语句 扩展一个语句的作用域链。
+ +

语法

+ +
with (expression) {
+    statement
+}
+
+ +
+
expression
+
将给定的表达式添加到在评估语句时使用的作用域链上。表达式周围的括号是必需的。
+
statement
+
任何语句。要执行多个语句,请使用一个语句 ({ ... })对这些语句进行分组。
+
+ +

描述

+ +

JavaScript查找某个未使用命名空间的变量时,会通过作用域链来查找,作用域链是跟执行代码的context或者包含这个变量的函数有关。'with'语句将某个对象添加到作用域链的顶部,如果在statement中有某个未使用命名空间的变量,跟作用域链中的某个属性同名,则这个变量将指向这个属性值。如果沒有同名的属性,则将拋出{{jsxref("ReferenceError")}}异常。

+ +
不推荐使用with,在 ECMAScript 5 严格模式中该标签已被禁止。推荐的替代方案是声明一个临时变量来承载你所需要的属性。
+ +

性能方面的利与弊

+ +

利:with语句可以在不造成性能损失的情況下,减少变量的长度。其造成的附加计算量很少。使用'with'可以减少不必要的指针路径解析运算。需要注意的是,很多情況下,也可以不使用with语句,而是使用一个临时变量来保存指针,来达到同样的效果。

+ +

弊:with语句使得程序在查找变量值时,都是先在指定的对象中查找。所以那些本来不是这个对象的属性的变量,查找起来将会很慢。如果是在对性能要求较高的场合,'with'下面的statement语句中的变量,只应该包含这个指定对象的属性。

+ +

语义不明的弊端

+ +

弊端:with语句使得代码不易阅读,同时使得JavaScript编译器难以在作用域链上查找某个变量,难以决定应该在哪个对象上来取值。请看下面的例子:

+ +
function f(x, o) {
+  with (o)
+    print(x);
+}
+ +

f被调用时,x有可能能取到值,也可能是undefined,如果能取到, 有可能是在o上取的值,也可能是函数的第一个参数x的值(如果o中没有这个属性的话)。如果你忘记在作为第二个参数的对象o中定义x这个属性,程序并不会报错,只是取到另一个值而已。

+ +

弊端:使用with语句的代码,无法向前兼容,特別是在使用一些原生数据类型的时候。看下面的例子:

+ +
+
function f(foo, values) {
+    with (foo) {
+        console.log(values)
+    }
+}
+
+ +

如果是在ECMAScript 5环境调用f([1,2,3], obj),则with语句中变量values将指向函数的第二个参数values。但是,ECMAScript 6标准给Array.prototype添加了一个新属性values,所有数组实例将继承这个属性。所以在ECMAScript 6环境中,with语句中变量values将指向[1,2,3].values

+
+ +

示例

+ +

Example: Using with

+ +

下面的with语句指定Math对象作为默认对象。with语句里面的变量,分別指向Math对象的PI 、cossin函数,不用在前面添加命名空间。后续所有引用都指向Math对象。

+ +
var a, x, y;
+var r = 10;
+
+with (Math) {
+  a = PI * r * r;
+  x = r * cos(PI);
+  y = r * sin(PI / 2);
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-with-statement', 'with statement')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-with-statement', 'with statement')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-12.10', 'with statement')}}{{Spec2('ES5.1')}}Now forbidden in strict mode.
{{SpecName('ES3', '#sec-12.10', 'with statement')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-12.10', 'with statement')}}{{Spec2('ES1')}}Initial definition
+ +

浏览器兼容

+ + + +

{{Compat("javascript.statements.with")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/strict_mode/index.html b/files/zh-cn/web/javascript/reference/strict_mode/index.html new file mode 100644 index 0000000000..4f48146e49 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/strict_mode/index.html @@ -0,0 +1,375 @@ +--- +title: 严格模式 +slug: Web/JavaScript/Reference/Strict_mode +tags: + - JavaS + - Strict Mode + - 严格模式 +translation_of: Web/JavaScript/Reference/Strict_mode +--- +
{{JsSidebar("More")}}
+ +
有时你会看到非严格模式,被称为“sloppy mode”。这不是一个官方术语,但以防万一,你应该意识到这一点。
+ +
ECMAScript 5严格模式是采用具有限制性JavaScript变体的一种方式,从而使代码显示地 脱离“马虎模式/稀松模式/懒散模式“(sloppy)模式。
+ +
严格模式不仅仅是一个子集:它的产生是为了形成与正常代码不同的语义。
+ +
不支持严格模式与支持严格模式的浏览器在执行严格模式代码时会采用不同行为。
+ +
所以在没有对运行环境展开特性测试来验证对于严格模式相关方面支持的情况下,就算采用了严格模式也不一定会取得预期效果。严格模式代码和非严格模式代码可以共存,因此项目脚本可以渐进式地采用严格模式。
+ +
+ +
严格模式对正常的 JavaScript语义做了一些更改。
+ +
+ +
    +
  1. 严格模式通过抛出错误来消除了一些原有静默错误
  2. +
  3. 严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快
  4. +
  5. 严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。
  6. +
+ +

如果你想改变你的代码,让其工作在具有限制性JavaScript环境中,请参阅转换成严格模式

+ +

调用严格模式

+ +

严格模式可以应用到整个脚本或个别函数中。不要在封闭大括弧 {} 内这样做,在这样的上下文中这么做是没有效果的eval 、Function 、内联事件处理属性、  {{domxref("WindowTimers.setTimeout()")}} 方法中传入的脚本字符串,其行为类似于开启了严格模式的一个单独脚本,它们会如预期一样工作。

+ +

为脚本开启严格模式

+ +

为整个脚本文件开启严格模式,需要在所有语句之前放一个特定语句 "use strict"; (或 'use strict';

+ +
// 整个脚本都开启严格模式的语法
+"use strict";
+var v = "Hi!  I'm a strict mode script!";
+
+ +

这种语法存在陷阱,有一个大型网站已经被它坑倒了:不能盲目的合并冲突代码。试想合并一个严格模式的脚本和一个非严格模式的脚本:合并后的脚本代码看起来是严格模式。反之亦然:非严格合并严格看起来是非严格的。合并均为严格模式的脚本或均为非严格模式的都没问题,只有在合并严格模式与非严格模式有可能有问题。建议按一个个函数去开启严格模式(至少在学习的过渡期要这样做).

+ +

您也可以将整个脚本的内容用一个函数包括起来,然后在这个外部函数中使用严格模式。这样做就可以消除合并的问题,但是这就意味着您必须要在函数作用域外声明一个全局变量。

+ +

为函数开启严格模式

+ +

同样的,要给某个函数开启严格模式,得把 "use strict";  (或 'use strict'; )声明一字不漏地放在函数体所有语句之前。

+ +
function strict() {
+  // 函数级别严格模式语法
+  'use strict';
+  function nested() {
+    return "And so am I!";
+  }
+  return "Hi!  I'm a strict mode function!  " + nested();
+}
+
+function notStrict() {
+  return "I'm not strict.";
+}
+
+ +

严格模式中的变化

+ +

严格模式同时改变了语法及运行时行为。变化通常分为这几类:将问题直接转化为错误(如语法错误或运行时错误), 简化了如何为给定名称的特定变量计算,简化了 eval 以及 arguments, 将写"安全“JavaScript的步骤变得更简单,以及改变了预测未来ECMAScript行为的方式。

+ +

将过失错误转成异常

+ +

在严格模式下, 某些先前被接受的过失错误将会被认为是异常. JavaScript被设计为能使新人开发者更易于上手, 所以有时候会给本来错误操作赋予新的不报错误的语义(non-error semantics). 有时候这可以解决当前的问题, 但有时候却会给以后留下更大的问题. 严格模式则把这些失误当成错误, 以便可以发现并立即将其改正.

+ +

第一,严格模式下无法再意外创建全局变量。在普通的JavaScript里面给一个错误命名的变量名赋值会使全局对象新增一个属性并继续“工作”(尽管将来可能会失败:在现代的JavaScript中有可能)。严格模式中意外创建全局变量被抛出错误替代:

+ +
"use strict";
+                       // 假如有一个全局变量叫做mistypedVariable
+mistypedVaraible = 17; // 因为变量名拼写错误
+                       // 这一行代码就会抛出 ReferenceError
+
+ +

第二, 严格模式会使引起静默失败(silently fail,注:不报错也没有任何效果)的赋值操作抛出异常. 例如, NaN 是一个不可写的全局变量. 在正常模式下, 给 NaN 赋值不会产生任何作用; 开发者也不会受到任何错误反馈. 但在严格模式下, 给 NaN 赋值会抛出一个异常. 任何在正常模式下引起静默失败的赋值操作 (给不可写属性赋值, 给只读属性(getter-only)赋值, 给不可扩展对象(non-extensible object)的新属性赋值) 都会抛出异常:

+ +
"use strict";
+
+// 给不可写属性赋值
+var obj1 = {};
+Object.defineProperty(obj1, "x", { value: 42, writable: false });
+obj1.x = 9; // 抛出TypeError错误
+
+// 给只读属性赋值
+var obj2 = { get x() { return 17; } };
+obj2.x = 5; // 抛出TypeError错误
+
+// 给不可扩展对象的新属性赋值
+var fixed = {};
+Object.preventExtensions(fixed);
+fixed.newProp = "ohai"; // 抛出TypeError错误
+
+ +

第三, 在严格模式下, 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果):

+ +
"use strict";
+delete Object.prototype; // 抛出TypeError错误
+
+ +

第四,在Gecko版本34之前,严格模式要求一个对象内的所有属性名在对象内必须唯一。正常模式下重名属性是允许的,最后一个重名的属性决定其属性值。因为只有最后一个属性起作用,当代码要去改变属性值而不是修改最后一个重名属性的时候,复制这个对象就产生一连串的bug。在严格模式下,重名属性被认为是语法错误:

+ +
+

这个问题在ECMAScript6中已经不复存在({{bug(1041128)}})。

+
+ +
"use strict";
+var o = { p: 1, p: 2 }; // !!! 语法错误
+
+ +

第五, 严格模式要求函数的参数名唯一. 在正常模式下, 最后一个重名参数名会掩盖之前的重名参数. 之前的参数仍然可以通过 arguments[i] 来访问, 还不是完全无法访问. 然而, 这种隐藏毫无意义而且可能是意料之外的 (比如它可能本来是打错了), 所以在严格模式下重名参数被认为是语法错误:

+ +
function sum(a, a, c) { // !!! 语法错误
+  "use strict";
+  return a + a + c; // 代码运行到这里会出错
+}
+
+ +

第六, 严格模式禁止八进制数字语法. ECMAScript并不包含八进制语法, 但所有的浏览器都支持这种以零(0)开头的八进制语法: 0644 === 420 还有 "\045" === "%".在ECMAScript 6中支持为一个数字加"0o"的前缀来表示八进制数.

+ +
var a = 0o10; // ES6: 八进制
+ +

有些新手开发者认为数字的前导零没有语法意义, 所以他们会用作对齐措施 — 但其实这会改变数字的意义! 八进制语法很少有用并且可能会错误使用, 所以严格模式下八进制语法会引起语法错误:

+ +
"use strict";
+var sum = 015 + // !!! 语法错误
+          197 +
+          142;
+
+ +

第七,ECMAScript 6中的严格模式禁止设置{{Glossary("primitive")}}值的属性.不采用严格模式,设置属性将会简单忽略(no-op),采用严格模式,将抛出{{jsxref("TypeError")}}错误

+ +
(function() {
+  "use strict";
+
+  false.true = "";              //TypeError
+  (14).sailing = "home";        //TypeError
+  "with".you = "far away";      //TypeError
+})();
+ +

简化变量的使用

+ +

严格模式简化了代码中变量名字映射到变量定义的方式. 很多编译器的优化是依赖存储变量X位置的能力:这对全面优化JavaScript代码至关重要. JavaScript有些情况会使得代码中名字到变量定义的基本映射只在运行时才产生. 严格模式移除了大多数这种情况的发生, 所以编译器可以更好的优化严格模式的代码.

+ +

第一, 严格模式禁用 withwith所引起的问题是块内的任何名称可以映射(map)到with传进来的对象的属性, 也可以映射到包围这个块的作用域内的变量(甚至是全局变量), 这一切都是在运行时决定的: 在代码运行之前是无法得知的. 严格模式下, 使用 with 会引起语法错误, 所以就不会存在 with 块内的变量在运行时才决定引用到哪里的情况了:

+ +
"use strict";
+var x = 17;
+with (obj) { // !!! 语法错误
+  // 如果没有开启严格模式,with中的这个x会指向with上面的那个x,还是obj.x?
+  // 如果不运行代码,我们无法知道,因此,这种代码让引擎无法进行优化,速度也就会变慢。
+  x;
+}
+
+ +

一种取代 with的简单方法是,将目标对象赋给一个短命名变量,然后访问这个变量上的相应属性.

+ +

第二, 严格模式下的 eval 不再为上层范围(surrounding scope,注:包围eval代码块的范围)引入新变量. 在正常模式下,  代码 eval("var x;") 会给上层函数(surrounding function)或者全局引入一个新的变量 x . 这意味着, 一般情况下,  在一个包含 eval 调用的函数内所有没有引用到参数或者局部变量的名称都必须在运行时才能被映射到特定的定义 (因为 eval 可能引入的新变量会覆盖它的外层变量). 在严格模式下 eval 仅仅为被运行的代码创建变量, 所以 eval 不会使得名称映射到外部变量或者其他局部变量:

+ +
var x = 17;
+var evalX = eval("'use strict'; var x = 42; x");
+console.assert(x === 17);
+console.assert(evalX === 42);
+
+ +

相应的, 如果函数 eval 被在严格模式下的eval(...)以表达式的形式调用时, 其代码会被当做严格模式下的代码执行. 当然也可以在代码中显式开启严格模式, 但这样做并不是必须的.

+ +
function strict1(str) {
+  "use strict";
+  return eval(str); // str中的代码在严格模式下运行
+}
+function strict2(f, str) {
+  "use strict";
+  return f(str); // 没有直接调用eval(...): 当且仅当str中的代码开启了严格模式时
+                 // 才会在严格模式下运行
+}
+function nonstrict(str) {
+  return eval(str); // 当且仅当str中的代码开启了"use strict",str中的代码才会在严格模式下运行
+}
+
+strict1("'Strict mode code!'");
+strict1("'use strict'; 'Strict mode code!'");
+strict2(eval, "'Non-strict code.'");
+strict2(eval, "'use strict'; 'Strict mode code!'");
+nonstrict("'Non-strict code.'");
+nonstrict("'use strict'; 'Strict mode code!'");
+
+ +

因此,在 eval 执行的严格模式代码下,变量的行为与严格模式下非 eval 执行的代码中的变量相同。

+ +

第三, 严格模式禁止删除声明变量。delete name 在严格模式下会引起语法错误:

+ +
"use strict";
+
+var x;
+delete x; // !!! 语法错误
+
+eval("var y; delete y;"); // !!! 语法错误
+
+ +

evalarguments变的简单

+ +

严格模式让argumentseval少了一些奇怪的行为。两者在通常的代码中都包含了很多奇怪的行为: eval会添加删除绑定,改变绑定好的值,还会通过用它索引过的属性给形参取别名的方式修改形参. 虽然在未来的ECMAScript版本解决这个问题之前,是不会有补丁来完全修复这个问题,但严格模式下将eval和arguments作为关键字对于此问题的解决是很有帮助的。

+ +

第一, 名称 eval 和 arguments 不能通过程序语法被绑定(be bound)或赋值. 以下的所有尝试将引起语法错误:

+ +
"use strict";
+eval = 17;
+arguments++;
+++eval;
+var obj = { set p(arguments) { } };
+var eval;
+try { } catch (arguments) { }
+function x(eval) { }
+function arguments() { }
+var y = function eval() { };
+var f = new Function("arguments", "'use strict'; return 17;");
+
+ +

第二,严格模式下,参数的值不会随 arguments 对象的值的改变而变化。在正常模式下,对于第一个参数是 arg 的函数,对 arg 赋值时会同时赋值给 arguments[0],反之亦然(除非没有参数,或者 arguments[0] 被删除)。严格模式下,函数的 arguments 对象会保存函数被调用时的原始参数。arguments[i] 的值不会随与之相应的参数的值的改变而变化,同名参数的值也不会随与之相应的 arguments[i] 的值的改变而变化。

+ +
function f(a) {
+  "use strict";
+  a = 42;
+  return [a, arguments[0]];
+}
+var pair = f(17);
+console.assert(pair[0] === 42);
+console.assert(pair[1] === 17);
+
+ +

第三,不再支持 arguments.callee。正常模式下,arguments.callee 指向当前正在执行的函数。这个作用很小:直接给执行函数命名就可以了!此外,arguments.callee 十分不利于优化,例如内联函数,因为 arguments.callee 会依赖对非内联函数的引用。在严格模式下,arguments.callee 是一个不可删除属性,而且赋值和读取时都会抛出异常:

+ +
"use strict";
+var f = function() { return arguments.callee; };
+f(); // 抛出类型错误
+
+ +

"安全的" JavaScript

+ +

严格模式下更容易写出“安全”的JavaScript。现在有些网站提供了方式给用户编写能够被网站其他用户执行的JavaScript代码。在浏览器环境下,JavaScript能够获取用户的隐私信息,因此这类Javascript必须在运行前部分被转换成需要申请访问禁用功能的权限。没有很多的执行时检查的情况,Javascript的灵活性让它无法有效率地做这件事。一些语言中的函数普遍出现,以至于执行时检查他们会引起严重的性能损耗。做一些在严格模式下发生的小改动,要求用户提交的JavaScript开启严格模式并且用特定的方式调用,就会大大减少在执行时进行检查的必要。

+ +

第一,在严格模式下通过this传递给一个函数的值不会被强制转换为一个对象。对一个普通的函数来说,this总会是一个对象:不管调用时this它本来就是一个对象;还是用布尔值,字符串或者数字调用函数时函数里面被封装成对象的this;还是使用undefined或者null调用函数式this代表的全局对象(使用callapply或者bind方法来指定一个确定的this)。这种自动转化为对象的过程不仅是一种性能上的损耗,同时在浏览器中暴露出全局对象也会成为安全隐患,因为全局对象提供了访问那些所谓安全的JavaScript环境必须限制的功能的途径。所以对于一个开启严格模式的函数,指定的this不再被封装为对象,而且如果没有指定this的话它值是undefined

+ +
"use strict";
+function fun() { return this; }
+console.assert(fun() === undefined);
+console.assert(fun.call(2) === 2);
+console.assert(fun.apply(null) === null);
+console.assert(fun.call(undefined) === undefined);
+console.assert(fun.bind(true)() === true);
+
+ +

第二,在严格模式中再也不能通过广泛实现的ECMAScript扩展“游走于”JavaScript的栈中。在普通模式下用这些扩展的话,当一个叫fun的函数正在被调用的时候,fun.caller是最后一个调用fun的函数,而且fun.arguments包含调用fun时用的形参。这两个扩展接口对于“安全”JavaScript而言都是有问题的,因为他们允许“安全的”代码访问"专有"函数和他们的(通常是没有经过保护的)形参。如果fun在严格模式下,那么fun.callerfun.arguments都是不可删除的属性而且在存值、取值时都会报错:

+ +
function restricted() {
+  "use strict";
+  restricted.caller;    // 抛出类型错误
+  restricted.arguments; // 抛出类型错误
+}
+
+function privilegedInvoker() {
+  return restricted();
+}
+
+privilegedInvoker();
+
+ +

第三,严格模式下的arguments不会再提供访问与调用这个函数相关的变量的途径。在一些旧时的ECMAScript实现中arguments.caller曾经是一个对象,里面存储的属性指向那个函数的变量。这是一个安全隐患,因为它通过函数抽象打破了本来被隐藏起来的保留值;它同时也是引起大量优化工作的原因。出于这些原因,现在的浏览器没有实现它。但是因为它这种历史遗留的功能,arguments.caller在严格模式下同样是一个不可被删除的属性,在赋值或者取值时会报错:

+ +
"use strict";
+function fun(a, b) {
+  "use strict";
+  var v = 12;
+  return arguments.caller; // 抛出类型错误
+}
+fun(1, 2); // 不会暴露v(或者a,或者b)
+
+ +

为未来的ECMAScript版本铺平道路

+ +

未来版本的ECMAScript很有可能会引入新语法,ECMAScript5中的严格模式就提早设置了一些限制来减轻之后版本改变产生的影响。如果提早使用了严格模式中的保护机制,那么做出改变就会变得更容易。

+ +

第一,在严格模式中一部分字符变成了保留的关键字。这些字符包括implements, interface, let, package, private, protected, public, staticyield。在严格模式下,你不能再用这些名字作为变量名或者形参名。

+ +
function package(protected) { // !!!
+  "use strict";
+  var implements; // !!!
+
+  interface: // !!!
+  while (true) {
+    break interface; // !!!
+  }
+
+  function private() { } // !!!
+}
+function fun(static) { 'use strict'; } // !!!
+
+ +

两个针对Mozilla开发的警告:第一,如果你的JavaScript版本在1.7及以上(你的chrome代码或者你正确使用了<script type="">)并且开启了严格模式的话,因为letyield是最先引入的关键字,所以它们会起作用。但是网络上用<script src="">或者<script>...</script>加载的代码,let或者yield都不会作为关键字起作用;第二,尽管ES5无条件的保留了class, enum, export, extends, importsuper关键字,在Firefox 5之前,Mozilla仅仅在严格模式中保留了它们。

+ +

第二,严格模式禁止了不在脚本或者函数层面上的函数声明。在浏览器的普通代码中,在“所有地方”的函数声明都是合法的。这并不在ES5规范中(甚至是ES3)!这是一种针对不同浏览器中不同语义的一种延伸。未来的ECMAScript版本很有希望制定一个新的,针对不在脚本或者函数层面进行函数声明的语法。在严格模式下禁止这样的函数声明对于将来ECMAScript版本的推出扫清了障碍:

+ +
"use strict";
+if (true) {
+  function f() { } // !!! 语法错误
+  f();
+}
+
+for (var i = 0; i < 5; i++) {
+  function f2() { } // !!! 语法错误
+  f2();
+}
+
+function baz() { // 合法
+  function eit() { } // 同样合法
+}
+
+ +

这种禁止放到严格模式中并不是很合适,因为这样的函数声明方式从ES5中延伸出来的。但这是ECMAScript委员会推荐的做法,浏览器就实现了这一点。

+ +

浏览器的严格模式

+ +

主流浏览器现在实现了严格模式。但是不要盲目的依赖它,因为市场上仍然有大量的浏览器版本只部分支持严格模式或者根本就不支持(比如IE10之前的版本)。严格模式改变了语义。依赖这些改变可能会导致没有实现严格模式的浏览器中出现问题或者错误。谨慎地使用严格模式,通过检测相关代码的功能保证严格模式不出问题。最后,记得在支持或者不支持严格模式的浏览器中测试你的代码。如果你只在不支持严格模式的浏览器中测试,那么在支持的浏览器中就很有可能出问题,反之亦然。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-10.1.1', 'Strict Mode Code')}}{{Spec2('ES5.1')}}Initial definition. See also: Strict mode restriction and exceptions
{{SpecName('ES6', '#sec-strict-mode-code', 'Strict Mode Code')}}{{Spec2('ES6')}}Strict mode restriction and exceptions
{{SpecName('ESDraft', '#sec-strict-mode-code', 'Strict Mode Code')}}{{Spec2('ESDraft')}}Strict mode restriction and exceptions
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/strict_mode/transitioning_to_strict_mode/index.html b/files/zh-cn/web/javascript/reference/strict_mode/transitioning_to_strict_mode/index.html new file mode 100644 index 0000000000..8973075e47 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/strict_mode/transitioning_to_strict_mode/index.html @@ -0,0 +1,128 @@ +--- +title: 向严格模式过渡 +slug: Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode +translation_of: Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode +--- +

{{jsSidebar("More")}}

+ +

ECMAScript 5 引入了 strict mode ,现在已经被大多浏览器实现(包括IE10. 会使web浏览器更容易的解析代码(只需要添加 "use strict"; 在源码的最上面), 由现有的代码到严格模式的过渡需要一些事做.

+ +

该文章旨在为开发者提供指南.

+ +

逐步过渡

+ +

严格模式被仔细设计过,因此可以逐渐地进行迁移。你可以分别改变各个文件,甚至以函数级的粒度迁移至严格模式。

+ +

非严格模式到严格模式的区别

+ +

语法错误

+ +

如果代码中使用"use strict"开启了严格模式,则下面的情况都会在脚本运行之前抛出SyntaxError异常:

+ + + +

这些错误是有利的,因为可以揭示简陋的错误和坏的实践,这些错误会在代码运行前被抛出

+ +

新的运行时错误

+ +

JavaScript曾经会在一些上下文的某些情况中静默的失败,严格模式会在这些情况下抛出错误。如果你的代码包含这样的场景,请务必测试以确保没有代码受到影响。再说一次,严格模式是可以设置在代码粒度下的。

+ +

给一个未声明的变量赋值

+ +
function f(x){
+  "use strict";
+  var a = 12;
+  b = a + x*35; // error!
+}
+f();
+
+ +

改变一个全局对象的值可能会造成不可预期的后果。如果你真的想设置一个全局对象的值,把他作为一个参数并且明确的把它作为一个属性:

+ +
var global = this; // in the top-level context, "this" always refers the global object
+function f(){
+  "use strict";
+  var a = 12;
+  global.b = a + x*35;
+}
+f();
+
+ +

尝试删除一个不可配置的属性

+ +
"use strict";
+delete Object.prototype; // error!
+
+ +

在非严格模式中,这样的代码只会静默失败,这样可能会导致用户误以为删除操作成功了.

+ +

arguments对象和函数属性

+ +

在严格模式下,访问arguments.callee, arguments.caller, anyFunction.caller以及anyFunction.arguments都会抛出异常.唯一合法的使用应该是在其中命名一个函数并且重用之

+ +
// example taken from vanillajs: http://vanilla-js.com/
+var s = document.getElementById('thing').style;
+s.opacity = 1;
+(function(){
+  if((s.opacity-=.1) < 0)
+    s.display="none";
+  else
+    setTimeout(arguments.callee, 40);
+})();
+ +

可以重新写成:

+ +
"use strict";
+var s = document.getElementById('thing').style;
+s.opacity = 1;
+(function fadeOut(){ // name the function
+  if((s.opacity-=.1) < 0)
+    s.display="none";
+  else
+    setTimeout(fadeOut, 40); // use the name of the function
+})();
+ +

语义差异

+ +

这些差异都是一些微小的差异。有可能单元测试没办法捕获这种微小的差异。你很有必要去小心地审查你的代码,来确保这些差异不会影响你代码的语义。幸运的是,这种小心地代码审查可以逐函数地完成。

+ +

函数调用中的this

+ +

在普通的函数调用f()中,this的值会指向全局对象.在严格模式中,this的值会指向undefined.当函数通过callapply调用时,如果传入的thisvalue参数是一个nullundefined除外的原始值(字符串,数字,布尔值),则this的值会成为那个原始值对应的包装对象,如果thisvalue参数的值是undefinednull,则this的值会指向全局对象.在严格模式中,this的值就是thisvalue参数的值,没有任何类型转换.

+ +

arguments对象属性不与对应的形参变量同步更新

+ +

在非严格模式中,修改arguments对象中某个索引属性的值,和这个属性对应的形参变量的值也会同时变化,反之亦然.这会让JavaScript的代码混淆引擎让代码变得更难读和理解。在严格模式中arguments 对象会以形参变量的拷贝的形式被创建和初始化,因此 arguments 对象的改变不会影响形参。

+ +

eval相关的区别

+ +

在严格模式中,eval不会在当前的作用域内创建新的变量.另外,传入eval的字符串参数也会按照严格模式来解析.你需要全面测试来确保没有代码收到影响。另外,如果你并不是为了解决一个非常实际的解决方案中,尽量不要使用eval。

+ +

严格中立的代码

+ +

迁移严格代码至严格模式的一个潜在消极面是,在遗留的老版本浏览器上,由于没有实现严格模式,javascript语义可能会有所不同。在一些罕见的机会下(比如差劲的关联关系或者代码最小化),你的代码可能不能按照你书写或者测试里的模式那样运行。这里有一些让你的代码保持中立的规范:

+ +
    +
  1. 按照严格模式书写你的代码,并且确保你的代码不会发生仅仅在严格模式下发生的错误(比如上文所说的运行时错误
  2. +
  3. 远离语义差异 +
      +
    1. eval: 仅仅在你知道你在干什么的情况下使用它
    2. +
    3. arguments: 总是通过形参的名字获取函数参数,或者在函数的第一行拷贝arguments 
      + var args = Array.prototype.slice.call(arguments)
    4. +
    5. this: 仅在this指向你自己创建的对象时使用它 
    6. +
    +
  4. +
diff --git a/files/zh-cn/web/javascript/reference/template_strings/index.html b/files/zh-cn/web/javascript/reference/template_strings/index.html new file mode 100644 index 0000000000..aec3adfb5b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/template_strings/index.html @@ -0,0 +1,261 @@ +--- +title: 模板字符串 +slug: Web/JavaScript/Reference/template_strings +tags: + - ECMAScript6 + - JavaScript + - Template string + - 模板字符串 +translation_of: Web/JavaScript/Reference/Template_literals +--- +
{{JsSidebar("More")}} 
+ +

模板字面量 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。它们在ES2015规范的先前版本中被称为“模板字符串”。

+ +

语法

+ +
`string text`
+
+`string text line 1
+ string text line 2`
+
+`string text ${expression} string text`
+
+tag `string text ${expression} string text`
+
+ +

描述

+ +

模板字符串使用反引号 (` `) 来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${expression})的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来,如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以通过该函数来对模板字符串进行操作处理。在模版字符串内使用反引号(`)时,需要在它前面加转义符(\)。

+ +
`\`` === "`" // --> true
+ +

多行字符串

+ +

在新行中插入的任何字符都是模板字符串中的一部分,使用普通字符串,你可以通过以下的方式获得多行字符串:

+ +
console.log('string text line 1\n' +
+'string text line 2');
+// "string text line 1
+// string text line 2"
+ +

要获得同样效果的多行字符串,只需使用如下代码:

+ +
console.log(`string text line 1
+string text line 2`);
+// "string text line 1
+// string text line 2"
+ +

插入表达式

+ +

在普通字符串中嵌入表达式,必须使用如下语法:

+ +

 

+ +
var a = 5;
+var b = 10;
+console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
+// "Fifteen is 15 and
+// not 20."
+ +

 

+ +

现在通过模板字符串,我们可以使用一种更优雅的方式来表示:

+ +

 

+ +
var a = 5;
+var b = 10;
+console.log(`Fifteen is ${a + b} and
+not ${2 * a + b}.`);
+// "Fifteen is 15 and
+// not 20."
+ +

 

+ +

嵌套模板

+ +

在某些时候,嵌套模板是具有可配置字符串的最简单也是更可读的方法。 在模板中,只需在模板内的占位符 ${ } 内使用它们,就可以轻松地使用内部反引号。 例如,如果条件 a 是真的,那么返回这个模板化的文字。

+ +

ES5:

+ +
var classes = 'header'
+classes += (isLargeScreen() ?
+   '' : item.isCollapsed ?
+     ' icon-expander' : ' icon-collapser');
+ +

在ES2015中使用模板文字而没有嵌套:

+ +
const classes = `header ${ isLargeScreen() ? '' :
+    (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;
+
+ +

 

+ +

在ES2015的嵌套模板字面量中:

+ +

 

+ +
const classes = `header ${ isLargeScreen() ? '' :
+ `icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;
+ +

 

+ +

 

+ +

带标签的模板字符串

+ +

更高级的形式的模板字符串是带标签的模板字符串。标签使您可以用函数解析模板字符串。标签函数的第一个参数包含一个字符串值的数组。其余的参数与表达式相关。最后,你的函数可以返回处理好的的字符串(或者它可以返回完全不同的东西 , 如下个例子所述)。用于该标签的函数的名称可以被命名为任何名字。

+ +
var person = 'Mike';
+var age = 28;
+
+function myTag(strings, personExp, ageExp) {
+
+  var str0 = strings[0]; // "that "
+  var str1 = strings[1]; // " is a "
+
+  // There is technically a string after
+  // the final expression (in our example),
+  // but it is empty (""), so disregard.
+  // var str2 = strings[2];
+
+  var ageStr;
+  if (ageExp > 99){
+    ageStr = 'centenarian';
+  } else {
+    ageStr = 'youngster';
+  }
+
+  return str0 + personExp + str1 + ageStr;
+
+}
+
+var output = myTag`that ${ person } is a ${ age }`;
+
+console.log(output);
+// that Mike is a youngster
+ +

正如下面例子所展示的,标签函数并不一定需要返回一个字符串。

+ +
function template(strings, ...keys) {
+  return (function(...values) {
+    var dict = values[values.length - 1] || {};
+    var result = [strings[0]];
+    keys.forEach(function(key, i) {
+      var value = Number.isInteger(key) ? values[key] : dict[key];
+      result.push(value, strings[i + 1]);
+    });
+    return result.join('');
+  });
+}
+
+var t1Closure = template`${0}${1}${0}!`;
+t1Closure('Y', 'A');  // "YAY!"
+var t2Closure = template`${0} ${'foo'}!`;
+t2Closure('Hello', {foo: 'World'});  // "Hello World!"
+ +

原始字符串

+ +

在标签函数的第一个参数中,存在一个特殊的属性raw ,我们可以通过它来访问模板字符串的原始字符串,而不经过特殊字符的替换。

+ +
function tag(strings) {
+  console.log(strings.raw[0]);
+}
+
+tag`string text line 1 \n string text line 2`;
+// logs "string text line 1 \n string text line 2" ,
+// including the two characters '\' and 'n'
+ +

另外,使用{{jsxref("String.raw()")}} 方法创建原始字符串和使用默认模板函数和字符串连接创建是一样的。

+ +
var str = String.raw`Hi\n${2+3}!`;
+// "Hi\n5!"
+
+str.length;
+// 6
+
+str.split('').join(',');
+// "H,i,\,n,5,!"
+
+ +

带标签的模版字面量及转义序列

+ +

自ES2016起,带标签的模版字面量遵守以下转义序列的规则:

+ + + +

这表示类似下面这种带标签的模版是有问题的,因为对于每一个ECMAScript语法,解析器都会去查找有效的转义序列,但是只能得到这是一个形式错误的语法:

+ +
latex`\unicode`
+// 在较老的ECMAScript版本中报错(ES2016及更早)
+// SyntaxError: malformed Unicode character escape sequence
+
+ +

ES2018关于非法转义序列的修订

+ +

带标签的模版字符串应该允许嵌套支持常见转义序列的语言(例如DSLsLaTeX)。ECMAScript提议模版字面量修订(第4阶段,将要集成到ECMAScript 2018标准) 移除对ECMAScript在带标签的模版字符串中转义序列的语法限制。

+ +

不过,非法转义序列在"cooked"当中仍然会体现出来。它们将以 {{jsxref("undefined")}} 元素的形式存在于"cooked"之中:

+ +
function latex(str) {
+ return { "cooked": str[0], "raw": str.raw[0] }
+}
+
+latex`\unicode`
+
+// { cooked: undefined, raw: "\\unicode" }
+ +

值得注意的是,这一转义序列限制只对带标签的模板字面量移除,而不包括不带标签的模板字面量:

+ +
let bad = `bad escape sequence: \unicode`;
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-template-literals', 'Template Literals')}}{{Spec2('ES2015')}}Initial definition. Defined in several section of the specification: Template Literals, Tagged Templates
{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}{{Spec2('ESDraft')}}Defined in several section of the specification: Template Literals, Tagged Templates
Template Literal RevisionStage 4 draftDrops escape sequence restriction from tagged templates
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.grammar.template_literals")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/trailing_commas/index.html b/files/zh-cn/web/javascript/reference/trailing_commas/index.html new file mode 100644 index 0000000000..5392602cc8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/trailing_commas/index.html @@ -0,0 +1,182 @@ +--- +title: 尾后逗号 +slug: Web/JavaScript/Reference/Trailing_commas +tags: + - Comma + - ECMAScript2017 + - ECMAScript5 + - JavaScript + - 语法 + - 逗号 +translation_of: Web/JavaScript/Reference/Trailing_commas +--- +
{{JsSidebar("More")}}
+ +

尾后逗号 (有时叫做“终止逗号”)在向 JavaScript 代码添加元素、参数、属性时十分有用。如果你想要添加新的属性,并且上一行已经使用了尾后逗号,你可以仅仅添加新的一行,而不需要修改上一行。这使得版本控制的代码比较(diff)更加清晰,代码编辑过程中遇到的麻烦更少。

+ +

JavaScript 一开始就支持数组字面量中的尾后逗号,随后向对象字面量(ECMAScript 5)中添加了尾后逗号。最近(ECMAScript 2017),又将其添加到函数参数中。

+ +

但是,{{Glossary("JSON")}} 不允许尾后逗号。

+ +

字面量中的尾后逗号

+ +

数组

+ +

JavaScript 忽略数组中的尾后逗号:

+ +
var arr = [
+  1,
+  2,
+  3,
+];
+
+arr; // [1, 2, 3]
+arr.length; // 3
+ +

如果使用了多于一个尾后逗号,会产生省略(elision,或者间隙 hole)。 带有间隙的数组叫做稀疏数组(sparse 紧凑数组 dense array 没有省略/间隙)。 例如,当使用 {{jsxref("Array.prototype.forEach()")}} 或 {{jsxref("Array.prototype.map()")}} 迭代数组时,会跳过数组间隙。

+ +
var arr = [1, 2, 3,,,];
+arr.length; // 5
+
+ +

对象

+ +

从 ECMAScript 5 开始,对象字面值中的尾后逗号也是符合语法的:

+ +
var object = {
+  foo: "bar",
+  baz: "qwerty",
+  age: 42,
+};
+ +

函数中的尾后逗号

+ +

ECMAScript 2017 支持函数参数中的尾后逗号。

+ +

参数定义

+ +

下面的两个函数定义都是合法的,并且互相等价。尾后逗号并不影响函数定义,或者其arguments对象的 length属性。

+ +
function f(p) {}
+function f(p,) {}
+
+(p) => {};
+(p,) => {};
+
+ +

尾后逗号也可用于类或对象的方法定义

+ +
class C {
+  one(a,) {},
+  two(a, b,) {},
+}
+
+var obj = {
+  one(a,) {},
+  two(a, b,) {},
+};
+
+ +

函数调用

+ +

下面的两个函数调用都是合法的,并且互相等价。

+ +
f(p);
+f(p,);
+
+Math.max(10, 20);
+Math.max(10, 20,);
+
+ +

不合法的尾后逗号

+ +

仅仅包含逗号的函数参数定义或者函数调用会抛出 {{Jsxref("SyntaxError")}}。 而且,当使用剩余参数的时候,并不支持尾后逗号:

+ +
function f(,) {} // SyntaxError: missing formal parameter
+(,) => {};       // SyntaxError: expected expression, got ','
+f(,)             // SyntaxError: expected expression, got ','
+
+function f(...p,) {} // SyntaxError: parameter after rest parameter
+(...p,) => {}        // SyntaxError: expected closing parenthesis, got ','
+
+ +

解构中的尾后逗号

+ +

在使用解构赋值时,尾后逗号也可以用于左侧:

+ +
// 带有尾后逗号的数组解构
+[a, b,] = [1, 2];
+
+// 带有尾后逗号的对象解构
+var o = {
+  p: 42,
+  q: true,
+};
+var {p, q,} = o;
+
+ +

同样地,在使用剩余参数时,会抛出 {{jsxref("SyntaxError")}}:

+ +
var [a, ...b,] = [1, 2, 3];
+// SyntaxError: rest element may not have a trailing comma
+ +

JSON 中的尾后逗号

+ +

对象中的尾后逗号仅仅在 ECMAScript 5 中引入。由于 JSON 基于 ES5 之前的语法, JSON 中并不允许尾后逗号

+ +

下面两行都会抛出 SyntaxError

+ +
JSON.parse('[1, 2, 3, 4, ]');
+JSON.parse('{"foo" : 1, }');
+// SyntaxError JSON.parse: unexpected character
+// at line 1 column 14 of the JSON data
+
+ +

去掉尾后逗号就行了:

+ +
JSON.parse('[1, 2, 3, 4 ]');
+JSON.parse('{"foo" : 1 }');
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES5.1')}}{{Spec2('ES5.1')}}Added object literal trailing commas.
{{SpecName('ES6')}}{{Spec2('ES6')}}No change.
{{SpecName('ES2017')}}{{Spec2('ES2017')}}Added trailing commas to function parameter lists and calls.
{{SpecName('ESDraft')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.grammar.trailing_commas")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/shells/index.html b/files/zh-cn/web/javascript/shells/index.html new file mode 100644 index 0000000000..a78e8f2f09 --- /dev/null +++ b/files/zh-cn/web/javascript/shells/index.html @@ -0,0 +1,47 @@ +--- +title: JavaScript shells编程环境 +slug: Web/JavaScript/Shells +tags: + - JavaScript + - 工具 + - 扩展 + - 指南 +translation_of: Web/JavaScript/Shells +--- +
{{JsSidebar}}
+ +

JavaScript shell 可以让你在不刷新一个网页的情况下测试一段 JavaScript 代码。这在开发和调试代码的时候非常有帮助。

+ +

独立的 JavaScript shells

+ +

下面的 JavaScript shells 是 Javascript 的独立运行环境,和 Perl、Python 一样。

+ +

【译注:下面的条目,前面是名字,后面是广告词之类的,就不翻译了】

+ + + +

JavaScript shells 列表

+ +

下面的 JavaScript shells 可以与Mozilla 一起工作。

+ + diff --git a/files/zh-cn/web/javascript/the_performance_hazards_of__[[prototype]]_mutation/index.html b/files/zh-cn/web/javascript/the_performance_hazards_of__[[prototype]]_mutation/index.html new file mode 100644 index 0000000000..aacff4c8d9 --- /dev/null +++ b/files/zh-cn/web/javascript/the_performance_hazards_of__[[prototype]]_mutation/index.html @@ -0,0 +1,142 @@ +--- +title: 'The performance hazards of [[Prototype]] mutation' +slug: 'Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation' +translation_of: 'Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation' +--- +

{{draft}}

+ +

{{jsSidebar("Advanced")}}

+ +

每个JavaScript对象都拥有一个[[Prototype]]对象。  获取一个对象的属性时首先会搜索其自身, 然后就是它的 [[Prototype]]对象, 之后再搜索此[[Prototype]]对象的 [[Prototype]]对象, 直到找到这个属性或者搜索链条达到终点. 这个类似链条的查找过程被称为原型链。  原型链在对象继承中非常重要。

+ +

ECMAScript 6 引入了一种方式来修改 [[Prototype]]对象。 提升了灵活性的代价是降低了性能。 修改[[Prototype]] 对象会损害降低所有现代 JavaScrip引擎的性能。这篇文章解释了修改 [[Prototype]] 对象在所有浏览器中都很慢的原因并给出了替代方案。

+ +

JavaScript引擎是如何提升访问对象属性的性能的

+ +

Objects are hashes, 所以理论上来说 (实际上也是如此) 访问属性所花费的时间是恒定不变的.  但是 "恒定不变" 的背后也可能有成千上万的机器指令.  幸运的是, 大多数情况下对象和属性是"可预测的", 在这些情况下它们的底层结构也是可预测的.  即时编译器可以据此来减少对象属性的访问所花费时间。

+ +

引擎根据添加到对象的顺序属性进行优化。大多数属性都是按照非常相似的顺序添加到对象中的。(经常使用obj[val]风格的随机访问访问对象是一个明显的例外。)

+ +
function Landmark(lat, lon, desc) {
+  this.location = { lat: lat, long: lon };
+  this.description = desc;
+}
+var lm1 = new Landmark(-90, 0, "South Pole");
+var lm2 = new Landmark(-24.3756466, -128.311018, "Pitcairn Islands");
+ +

在上面的例子中,每生成一个 Landmark 对象时都将按照 location 和 description 两个属性顺序加载,而存储“经度/纬度”信息的 location 也具有 lat 到 long 的顺序。随后的代码可以删除一个属性。但这是不可能的,因为引擎在这种情况下会生成一段不太理想的代码。在 SpiderMonkey (火狐的 JavaScript 引擎)里,属性的特定顺序(以及属性的其他一些方面,但不包括值)我们称之为“形状”(shape)(谷歌 V8 引擎里,这个概念名为“结构ID”(structure ID))。如果两个对象共享同一个 shape,那么他们属性的存储也相同。

+ +

Landmark 对象在引擎内部的(简化)版本如同下面的 C++:

+ +
struct Property {
+  Property* prev; // null if first property
+  String name; // name of property
+  unsigned int index; // index of its value in storage
+};
+using Shape = Property*;
+struct Object {
+  Shape shape;
+  Value* properties;
+  Object* prototype;
+};
+ +

例子中的JS表达式对应下面的 C++:

+ +
lm1->properties[0]; // loc1.location
+lm1->properties[1]; // loc1.description
+lm2->properties[0].toObject()->properties[1]; // loc2.location.long
+ +

如果引擎知道一个对象具有特殊 shape,就可以根据 shape 假定这个对象所有属性的索引。这样一来进行一次访问特定属性,也就相当于几个指针访问所花费的时间。机器语言去检查对象是否具有特定 shape 也很容易,如果有,那么假定索引快速访问;如果没有,那么慢慢来。

+ +

Naively optimizing inherited properties

+ +

Many properties don't exist directly on the object: lookups often find properties on the prototype chain.  Accesses to properties on prototypes is just extra "hops" through the prototype field to the object containing the property.  Optimizing correctly requires that no object along the way have the property, so every hop must check that object's shape.

+ +
var d = new Date();
+d.toDateString(); // Date.prototype.toDateString
+
+function Pair(x, y) { this.x = x; this.y = y; }
+Pair.prototype.sum = function() { return this.x + this.y; };
+
+var p = new Pair(3, 7);
+p.sum(); // Pair.prototype.sum
+ +

Engines take this quick-and-dirty approach in many cases.  But in especially performance-sensitive JavaScript, this isn't good enough.

+ +

Intelligently optimizing inherited properties

+ +

Predictable property accesses usually find the property a constant number of hops along the [[Prototype]] chain; intervening objects usually don't acquire new properties; the ultimate object usually won't have any properties deleted.  Finally: [[Prototype]] mutation is rare.  All these common assumptions are necessary to avoid slow prototype-hopping.  Different engines choose different approaches to intelligently optimize inherited properties.

+ +
+
The shape of the ultimate object containing the inherited can be checked.
+
In this case, a shape match must imply that no intervening object's [[Prototype]] has been modified.  Therefore, when an object's [[Prototype]] is mutated, every object along its [[Prototype]] chain must also have its shape changed.
+
+
var obj1 = {};
+var obj2 = Object.create(obj1);
+var obj3 = Object.create(obj2);
+
+// Objects whose shapes would change: obj3, obj2, obj1, Object.prototype
+obj3.__proto__ = {};
+
+
The shape of the object initially accessed can be checked.
+
Every object that might inherit through a changed-[[Prototype]] object must change, reflecting the [[Prototype]] mutation having happened
+
+
var obj1 = {};
+var obj2 = Object.create(obj1);
+var obj3 = Object.create(obj2);
+
+// Objects whose shapes would change: obj1, obj2, obj3
+obj1.__proto__ = {};
+
+
+ +

Pernicious effects of [[Prototype]] mutation

+ +

[[Prototype]] mutation's adverse performance impact occurs in two phases: at the time mutation occurs, and in subsequent execution.  First, mutating [[Prototype]] is slow.  Second, mutating [[Prototype]] slows down code that interacts with mutated-[[Prototype]] objects.

+ +

Mutating [[Prototype]] is slow

+ +

While the spec considers mutating [[Prototype]] to be modifying a single hidden property, real-world implementations are considerably more complex.  Both shape-changing tactics described above require examining (and modifying) more than one object.  Which approach modifies fewer objects in practice, depends upon the workload.

+ +

Mutated [[Prototype]]s slow down other code

+ +

The bad effects of [[Prototype]] mutation don't end once the mutation is complete.  Because so many property-examination operations implicitly depend on [[Prototype]] chains not changing, when engines observe a mutation, an object with mutated [[Prototype]] "taints" all code the object flows through.  This tainting flows through all code that ever observes a mutated-[[Prototype]] object.  As a near-worst-case illustration, consider these patterns of behavior:

+ +
var obj = {};
+obj.__proto__ = { x: 3 }; // gratuitous mutation
+
+var arr = [obj];
+for (var i = 0; i < 5; i++)
+  arr.push({ x: i });
+
+function f(v, i) {
+  var elt = v[i];
+  var r =  elt.x > 2 // pessimized
+           ? elt
+           : { x: elt.x + 1 };
+  return r;
+}
+var c = f(arr, 0);
+c.x; // pessimized: return value has unknown properties
+c = f(arr, 1);
+c.x; // still pessimized!
+
+var arr2 = [c];
+arr2[0].x; // pessimized
+
+ +

(Only code that runs many times is optimized, so this doesn't trigger all these bad behaviors.  But every breakdown could happen if it appeared in "hot" code.)

+ +

Recognizing exactly where a mutated-[[Prototype]] object flows, often across multiple scripts, is extraordinarily difficult.  It depends on careful textual analysis of the code and particular runtime behaviors.  Far-distant changes, that trigger subtly different control flow, can taint previously-optimal code paths with pessimal behavior.  It's impossible to recognize all the places that will become slower, even for a JavaScript language implementer.

+ +

remaining constant.Mutation must, in addition to changing other objects' shapes,

+ +

 

+ +

  But this requires storing cross-object information.

+ +

Cross-object information is different from shape, in that it can't easily be checked.  One modification to this information may affect many locations, none obviously connected to it: where to look to verify assumptions?  So instead of checking the assumptions before use, all code making assumptions is invalidated when a modification happens.  When a [[Prototype]] changes, all code depending on it must be thrown away.  The operation obj.__proto__ = ... is thus inherently slow.  And by throwing away already-optimized code, it makes that code much slower when it runs later.

+ +

But it's worse than that.  When evaluating obj.prop sees an object whose [[Prototype]] has been mutated, so much previously-known information about the object becomes useless that SpiderMonkey considers the object to have wholly-unknown characteristics.  Any code path that touches such an object in the future will assume the worst.  Optimizing JIT engines assume that future execution is like past execution.  If an object with mutated [[Prototype]] is observed by some code, that code will likely observe more such objects.  Therefore, operations that interact with an object with mutated [[Prototype]], anywhere, in any scripts, are un-optimizable.

+ +

The un-optimizability of objects with mutated [[Prototype]] is not

diff --git a/files/zh-cn/web/javascript/typed_arrays/index.html b/files/zh-cn/web/javascript/typed_arrays/index.html new file mode 100644 index 0000000000..409884d513 --- /dev/null +++ b/files/zh-cn/web/javascript/typed_arrays/index.html @@ -0,0 +1,174 @@ +--- +title: JavaScript 类型化数组 +slug: Web/JavaScript/Typed_arrays +tags: + - Array + - Typed + - Typed_arrays +translation_of: Web/JavaScript/Typed_arrays +--- +
{{JsSidebar("Advanced")}}
+ +

JavaScript类型化数组是一种类似数组的对象,并提供了一种用于访问原始二进制数据的机制。 正如你可能已经知道,{{jsxref("Array")}} 存储的对象能动态增多和减少,并且可以存储任何JavaScript值。JavaScript引擎会做一些内部优化,以便对数组的操作可以很快。然而,随着Web应用程序变得越来越强大,尤其一些新增加的功能例如:音频视频编辑,访问WebSockets的原始数据等,很明显有些时候如果使用JavaScript代码可以快速方便地通过类型化数组来操作原始的二进制数据将会非常有帮助。

+ +

但是,不要把类型化数组与正常数组混淆,因为在类型数组上调用  {{jsxref("Array.isArray()")}}  会返回false。此外,并不是所有可用于正常数组的方法都能被类型化数组所支持(如 push 和 pop)。

+ +

缓冲和视图:类型数组架构

+ +

为了达到最大的灵活性和效率,JavaScript 类型数组(Typed Arrays)将实现拆分为缓冲视图两部分。一个缓冲(由 {{jsxref("ArrayBuffer")}} 对象实现)描述的是一个数据块。缓冲没有格式可言,并且不提供机制访问其内容。为了访问在缓冲对象中包含的内存,你需要使用视图。视图提供了上下文 — 即数据类型、起始偏移量和元素数 — 将数据转换为实际有类型的数组。

+ +

Typed arrays in an ArrayBuffer

+ +

ArrayBuffer

+ +

 {{jsxref("ArrayBuffer")}} 是一种数据类型,用来表示一个通用的、固定长度的二进制数据缓冲区。你不能直接操纵一个ArrayBuffer中的内容;你需要创建一个类型化数组的视图或一个描述缓冲数据格式的{{jsxref("DataView")}},使用它们来读写缓冲区中的内容.

+ +

类型数组视图

+ +

类型化数组视图具有自描述性的名字和所有常用的数值类型像Int8Uint32Float64 等等。有一种特殊类型的数组Uint8ClampedArray。它仅操作0到255之间的数值。例如,这对于Canvas数据处理非常有用。

+ +

{{page("/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray", "TypedArray_objects")}}

+ +

数据视图

+ +

{{jsxref("DataView")}} 是一种底层接口,它提供有可以操作缓冲区中任意数据的读写接口。这对操作不同类型数据的场景很有帮助,例如:类型化数组视图都是运行在本地字节序模式(参考 {{Glossary("Endianness")}}),可以通过使用 DataView 来控制字节序。默认是大端字节序(Big-endian),但可以调用读写接口改为小端字节序(Little-endian)。

+ +

使用类型数组的Web API

+ +
+
FileReader.prototype.readAsArrayBuffer()
+
FileReader.prototype.readAsArrayBuffer() 读取对应的Blob 或 File的内容
+
XMLHttpRequest.prototype.send()
+
XMLHttpRequest 实例的 send() 方法现在使用支持类型化数组和 {{jsxref("ArrayBuffer")}} 对象作为参数。
+
ImageData.data
+
是一个 {{jsxref("Uint8ClampedArray")}} 对象,用来描述包含按照RGBA序列的颜色数据的一维数组,其值的范围在0255(包含255)之间。
+
+ +

示例

+ +

使用视图和缓冲

+ +

首先,我们创建一个16字节固定长度的缓冲:

+ +
var buffer = new ArrayBuffer(16);
+ +

现在我们有了一段初始化为0的内存,目前还做不了什么太多操作。让我们确认一下数据的字节长度:

+ +
if (buffer.byteLength === 16) {
+  console.log("Yes, it's 16 bytes.");
+} else {
+  console.log("Oh no, it's the wrong size!");
+}
+ +

在实际开始操作这个缓冲之前,需要创建一个视图。我们将创建一个视图,此视图将把缓冲内的数据格式化为一个32位的有符号整数数组:

+ +
var int32View = new Int32Array(buffer);
+ +

现在我们可以像普通数组一样访问该数组中的元素:

+ +
for (var i = 0; i < int32View.length; i++) {
+  int32View[i] = i * 2;
+}
+ +

该代码会将数组以0, 2, 4和6填充 (一共4个4字节元素,所以总长度为16字节)。

+ +

同一数据的多个视图

+ +

更有意思的是,你可以在同一数据上创建多个视图。例如:基于上文的代码,我们可以添加如下代码处理:

+ +
var int16View = new Int16Array(buffer);
+
+for (var i = 0; i < int16View.length; i++) {
+  console.log("Entry " + i + ": " + int16View[i]);
+}
+ +

这里我们创建了一个2字节整数视图,该视图共享上文的4字节整数视图的缓冲,然后以2字节整数打印出缓冲里的数据,这次我们会得到0, 0, 2, 0, 4, 0, 6, 0这样的输出。

+ +

那么,这样呢?

+ +
int16View[0] = 32;
+console.log("Entry 0 in the 32-bit array is now " + int32View[0]);
+ +

这次的输出是"Entry 0 in the 32-bit array is now 32"。也就是,这2个数组都是同一数据的以不同格式展示出来的视图。你可以使用任何一种 view types 中的定义的视图。

+ +

使用复杂的数据结构

+ +

通过将缓冲与不同类型视图组合,以及修改内存访问的偏移位置,你可以操作包含更多更复杂数据结构的数据。你可以使用js-ctypes操作诸如WebGL,数据文件或C语言结构体这些复杂的数据结构。

+ +

请看如下的C语言结构:

+ +
struct someStruct {
+  unsigned long id;
+  char username[16];
+  float amountDue;
+};
+ +

你可以采用如下代码访问一个包含此类结构体的缓冲:

+ +
var buffer = new ArrayBuffer(24);
+
+// ... read the data into the buffer ...
+
+var idView = new Uint32Array(buffer, 0, 1);
+var usernameView = new Uint8Array(buffer, 4, 16);
+var amountDueView = new Float32Array(buffer, 20, 1);
+ +

现在你就可以通过amountDueView[0]的方式访问数量。

+ +
+

提示:C语言结构体的数据对齐与平台相关。因此需要防范和考虑不同平台的字节填充对齐。

+
+ +

转换为普通数组

+ +

在处理完一个类型化数组后,有时需要把它转为普通数组,以便可以可以像普通数据一种操作访问。可以调用 {{jsxref("Array.from")}}实现这种转换,如果 Array.from 不支持的话,也可以通过如下代码实现:

+ +
var typedArray = new Uint8Array([1, 2, 3, 4]),
+    normalArray = Array.prototype.slice.call(typedArray);
+normalArray.length === 4;
+normalArray.constructor === Array;
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Typed Array')}}{{Spec2('Typed Array')}}Superseded by ECMAScript 2015.
{{SpecName('ES2015', '#sec-typedarray-objects', 'TypedArray Objects')}}{{Spec2('ES2015')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-typedarray-objects', 'TypedArray Objects')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.TypedArray")}}

+ +

了解更多

+ + + +
 
-- cgit v1.2.3-54-g00ecf